Full Code of timvisee/ffsend for AI

master 85aae2f3e83a cached
101 files
637.0 KB
157.6k tokens
379 symbols
1 requests
Download .txt
Showing preview only (668K chars total). Download the full file or copy to clipboard to get everything.
Repository: timvisee/ffsend
Branch: master
Commit: 85aae2f3e83a
Files: 101
Total size: 637.0 KB

Directory structure:
gitextract_5263lj6x/

├── .gitattributes
├── .github/
│   └── FUNDING.yml
├── .gitignore
├── .gitlab-ci.yml
├── .travis.yml
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE
├── README.md
├── SECURITY.md
├── appveyor.yml
├── build.rs
├── contrib/
│   ├── completions/
│   │   ├── _ffsend
│   │   ├── _ffsend.ps1
│   │   ├── ffsend.bash
│   │   ├── ffsend.elv
│   │   ├── ffsend.fish
│   │   └── gen_completions
│   └── util/
│       └── nautilus/
│           ├── README.md
│           └── firefox-send
├── pkg/
│   ├── alpine/
│   │   └── APKBUILD
│   ├── aur/
│   │   ├── aur.pub
│   │   ├── ffsend/
│   │   │   └── PKGBUILD
│   │   ├── ffsend-bin/
│   │   │   └── PKGBUILD
│   │   └── ffsend-git/
│   │       └── PKGBUILD
│   ├── choco/
│   │   └── ffsend/
│   │       ├── ffsend.nuspec
│   │       └── tools/
│   │           ├── LICENSE.txt
│   │           └── VERIFICATION.txt
│   ├── create_deb
│   ├── deb/
│   │   ├── postinst
│   │   └── prerm
│   ├── docker/
│   │   └── Dockerfile
│   └── scoop/
│       ├── README.md
│       └── ffsend.json
├── res/
│   ├── asciinema-demo.json
│   └── asciinema-to-svg
└── src/
    ├── action/
    │   ├── debug.rs
    │   ├── delete.rs
    │   ├── download.rs
    │   ├── exists.rs
    │   ├── generate/
    │   │   ├── completions.rs
    │   │   └── mod.rs
    │   ├── history.rs
    │   ├── info.rs
    │   ├── mod.rs
    │   ├── params.rs
    │   ├── password.rs
    │   ├── upload.rs
    │   └── version.rs
    ├── archive/
    │   ├── archive.rs
    │   ├── archiver.rs
    │   └── mod.rs
    ├── client.rs
    ├── cmd/
    │   ├── arg/
    │   │   ├── api.rs
    │   │   ├── basic_auth.rs
    │   │   ├── download_limit.rs
    │   │   ├── expiry_time.rs
    │   │   ├── gen_passphrase.rs
    │   │   ├── host.rs
    │   │   ├── mod.rs
    │   │   ├── owner.rs
    │   │   ├── password.rs
    │   │   └── url.rs
    │   ├── handler.rs
    │   ├── matcher/
    │   │   ├── debug.rs
    │   │   ├── delete.rs
    │   │   ├── download.rs
    │   │   ├── exists.rs
    │   │   ├── generate/
    │   │   │   ├── completions.rs
    │   │   │   └── mod.rs
    │   │   ├── history.rs
    │   │   ├── info.rs
    │   │   ├── main.rs
    │   │   ├── mod.rs
    │   │   ├── params.rs
    │   │   ├── password.rs
    │   │   ├── upload.rs
    │   │   └── version.rs
    │   ├── mod.rs
    │   └── subcmd/
    │       ├── debug.rs
    │       ├── delete.rs
    │       ├── download.rs
    │       ├── exists.rs
    │       ├── generate/
    │       │   ├── completions.rs
    │       │   └── mod.rs
    │       ├── history.rs
    │       ├── info.rs
    │       ├── mod.rs
    │       ├── params.rs
    │       ├── password.rs
    │       ├── upload.rs
    │       └── version.rs
    ├── config.rs
    ├── error.rs
    ├── history.rs
    ├── history_tool.rs
    ├── host.rs
    ├── main.rs
    ├── progress.rs
    ├── urlshorten.rs
    └── util.rs

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Mark generated completion files as vendored
contrib/completions/* linguist-vendored
contrib/completions/gen_completions linguist-vendored=false


================================================
FILE: .github/FUNDING.yml
================================================
# Funding links
github:
  - timvisee
custom:
  - "https://timvisee.com/donate"
patreon: timvisee
ko_fi: timvisee


================================================
FILE: .gitignore
================================================
.*.sw[po]
target/
**/*.rs.bk
.idea/
snapcraft.login


================================================
FILE: .gitlab-ci.yml
================================================
# GitLab CI configuration for ffsend builds, tests and releases
#
# To add a new release:
# - configure a new 'build-*' job with the proper target
# - export a build artifact from the new job
# - manually upload artifact to GitHub in the 'github-release' job

image: "rust:slim-bookworm"

stages:
  - check
  - build
  - test
  - release
  - package

# Variable defaults
variables:
  RUST_VERSION: stable
  RUST_TARGET: x86_64-unknown-linux-gnu

# Cache rust/cargo/build artifacts
cache:
  key: "$CI_PIPELINE_ID-$RUST_VERSION"
  paths:
    - /usr/local/cargo/registry/
    - /usr/local/rustup/toolchains/
    - /usr/local/rustup/update-hashes/
    - target/

# Install compiler and OpenSSL dependencies
before_script:
  - apt-get update
  - apt-get install -y --no-install-recommends build-essential pkg-config libssl-dev
  - |
    rustup install $RUST_VERSION
    rustup default $RUST_VERSION
  - |
    rustc --version
    cargo --version

# Check on stable, beta and nightly
.check-base: &check-base
  stage: check
  script:
    - cargo check --verbose
    - cargo check --no-default-features --features send3,crypto-ring --verbose
    - cargo check --no-default-features --features send2,crypto-openssl --verbose
    - cargo check --no-default-features --features send3,crypto-openssl --verbose
    - cargo check --no-default-features --features send2,send3,crypto-openssl --verbose
    - cargo check --no-default-features --features send3,crypto-ring,archive --verbose
    - cargo check --no-default-features --features send3,crypto-ring,history --verbose
    - cargo check --no-default-features --features send3,crypto-ring,qrcode --verbose
    - cargo check --no-default-features --features send3,crypto-ring,urlshorten --verbose
    - cargo check --no-default-features --features send3,crypto-ring,infer-command --verbose
    - cargo check --features no-color --verbose
check-stable:
  <<: *check-base
check-beta:
  <<: *check-base
  variables:
    RUST_VERSION: beta
check-nightly:
  <<: *check-base
  variables:
    RUST_VERSION: nightly
check-msrv:
  <<: *check-base
  variables:
    RUST_VERSION: "1.63.0"

# Build using Rust stable
build-x86_64-linux-gnu:
  stage: build
  needs: []
  script:
    - cargo build --target=$RUST_TARGET --release --verbose
    - mv target/$RUST_TARGET/release/ffsend ./ffsend-$RUST_TARGET
    - strip -g ./ffsend-$RUST_TARGET
  artifacts:
    name: ffsend-x86_64-linux-gnu
    paths:
      - ffsend-$RUST_TARGET
    expire_in: 1 month

# Build a static version
build-x86_64-linux-musl:
  stage: build
  needs: []
  variables:
    RUST_TARGET: x86_64-unknown-linux-musl
  script:
    # Install the static target
    - rustup target add $RUST_TARGET

    # Build OpenSSL statically
    - apt-get install -y build-essential wget musl-tools
    - wget https://github.com/openssl/openssl/releases/download/openssl-3.0.15/openssl-3.0.15.tar.gz
    - tar xzvf openssl-3.0.15.tar.gz
    - cd openssl-3.0.15
    - ./config no-async -fPIC --openssldir=/usr/local/ssl --prefix=/usr/local
    - make
    - make install
    - cd ..

    # Statically build ffsend
    - export OPENSSL_STATIC=1
    - export OPENSSL_LIB_DIR=/usr/local/lib64
    - export OPENSSL_INCLUDE_DIR=/usr/local/include
    - cargo build --target=$RUST_TARGET --release --verbose

    # Prepare the release artifact, strip it
    - find . -name ffsend -exec ls -lah {} \;
    - mv target/$RUST_TARGET/release/ffsend ./ffsend-$RUST_TARGET
    - strip -g ./ffsend-$RUST_TARGET
  artifacts:
    name: ffsend-x86_64-linux-musl
    paths:
      - ffsend-$RUST_TARGET
    expire_in: 1 month

# Run the unit tests through Cargo
test-cargo:
  stage: test
  needs: []
  dependencies: []
  script:
    - cargo test --verbose

# Run integration test with the public Send service
test-public:
  image: alpine:latest
  stage: test
  dependencies:
    - build-x86_64-linux-musl
  variables:
    GIT_STRATEGY: none
    RUST_TARGET: x86_64-unknown-linux-musl
  before_script: []
  script:
    # Prepare ffsend binary, create random file
    - mv ./ffsend-$RUST_TARGET ./ffsend
    - chmod a+x ./ffsend
    - head -c1m </dev/urandom >test.txt

    # Generate random file, upload/download and assert equality
    - ./ffsend upload test.txt -I
    - ./ffsend download $(./ffsend history -q) -I -o=download.txt
    - "cmp -s ./test.txt ./download.txt || (echo ERROR: Downloaded file is different than original; exit 1)"
    - rm ./download.txt

# Cargo crate release
release-crate:
  stage: release
  dependencies: []
  only:
    - /^v(\d+\.)*\d+$/
  script:
    - echo "Creating release crate to publish on crates.io..."
    - echo $CARGO_TOKEN | cargo login
    - echo "Publishing crate to crates.io..."
    - cargo publish --verbose --allow-dirty

# Snap release
release-snap:
  image: snapcore/snapcraft:stable
  stage: release
  dependencies: []
  only:
    - /^v(\d+\.)*\d+$/
  before_script: []
  script:
    # Prepare the environment
    - apt-get update -y
    - apt-get install python3 -yqq
    - cd pkg/snap

    # Update version number in snapcraft.yaml
    - VERSION=$(echo $CI_COMMIT_REF_NAME | cut -c 2-)
    - echo "Determined binary version number 'v$VERSION', updating snapcraft.yaml..."
    - 'sed "s/^version:.*\$/version: $VERSION/" -i snapcraft.yaml'
    - 'sed "s/^pkgver=.*\$/pkgver=$VERSION/" -i snapcraft.yaml'

    # Build the package
    - echo "Building snap package..."
    - snapcraft

    # Publish snap package
    - echo "Publishing snap package..."
    - snapcraft whoami
    - snapcraft push --release=stable ffsend_*_amd64.snap
  artifacts:
    name: ffsend-snap-x86_64
    paths:
      - pkg/snap/ffsend_*_amd64.snap
    expire_in: 1 month

# Publish release binaries to as GitHub release
release-github:
  stage: release
  only:
    - /^v(\d+\.)*\d+$/
  dependencies:
    - build-x86_64-linux-gnu
    - build-x86_64-linux-musl
  before_script: []
  script:
    # Install dependencies
    - apt-get update
    - apt-get install -y curl wget gzip netbase

    # Download github-release binary
    - wget https://github.com/tfausak/github-release/releases/download/1.2.5/github-release-linux.gz -O github-release.gz
    - gunzip github-release.gz
    - chmod a+x ./github-release

    # Create the release, upload binaries
    - ./github-release release --token "$GITHUB_TOKEN" --owner timvisee --repo ffsend --tag "$CI_COMMIT_REF_NAME"  --title "ffsend $CI_COMMIT_REF_NAME"
    - ./github-release upload --token "$GITHUB_TOKEN" --owner timvisee --repo ffsend --tag "$CI_COMMIT_REF_NAME" --file ./ffsend-x86_64-unknown-linux-gnu --name ffsend-$CI_COMMIT_REF_NAME-linux-x64
    - ./github-release upload --token "$GITHUB_TOKEN" --owner timvisee --repo ffsend --tag "$CI_COMMIT_REF_NAME" --file ./ffsend-x86_64-unknown-linux-musl --name ffsend-$CI_COMMIT_REF_NAME-linux-x64-static

# Publish a Docker image
release-docker:
  image: docker:git
  stage: release
  only:
    - /^v(\d+\.)*\d+$/
  dependencies:
    - build-x86_64-linux-musl
  services:
    - docker:dind
  variables:
    RUST_TARGET: x86_64-unknown-linux-musl
    DOCKER_HOST: tcp://docker:2375
    # DOCKER_DRIVER: overlay2
  before_script: []
  script:
    # Place binary in Docker directory, change to it
    - mv ./ffsend-$RUST_TARGET ./pkg/docker/ffsend
    - cd ./pkg/docker

    # Build the Docker image, run it once to test
    - docker build -t timvisee/ffsend:latest ./
    - docker run --rm timvisee/ffsend:latest -V

    # Retag version
    - VERSION=$(echo $CI_COMMIT_REF_NAME | cut -c 2-)
    - echo "Determined Docker image version number 'v$VERSION', retagging image..."
    - docker tag timvisee/ffsend:latest timvisee/ffsend:$VERSION

    # Authenticate and push the Docker images
    - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USER" --password-stdin
    - docker push timvisee/ffsend:$VERSION
    - docker push timvisee/ffsend:latest

# AUR packages release
package-aur:
  image: archlinux
  stage: package
  needs:
    - release-github
  dependencies: []
  only:
    - /^v(\d+\.)*\d+$/
  before_script: []
  script:
    - cd ./pkg/aur

    # Determine the version number we're releasing for
    - VERSION=$(echo $CI_COMMIT_REF_NAME | cut -c 2-)
    - echo "Determined binary version number 'v$VERSION'"

    # Determine remote URLs and SHA checksums
    - echo "Determining SHA checksums for remote files..."
    - URL_BIN=https://github.com/timvisee/ffsend/releases/download/v$VERSION/ffsend-v$VERSION-linux-x64-static
    - URL_SOURCE=https://gitlab.com/timvisee/ffsend/-/archive/v$VERSION/ffsend-v$VERSION.tar.gz
    - URL_BASH_COMPLETION=https://gitlab.com/timvisee/ffsend/raw/v$VERSION/contrib/completions/ffsend.bash
    - URL_ZSH_COMPLETION=https://gitlab.com/timvisee/ffsend/raw/v$VERSION/contrib/completions/_ffsend
    - URL_FISH_COMPLETION=https://gitlab.com/timvisee/ffsend/raw/v$VERSION/contrib/completions/ffsend.fish
    - URL_LICENSE=https://gitlab.com/timvisee/ffsend/raw/v$VERSION/LICENSE
    - 'echo "Selected binary URL: $URL_BIN"'
    - 'echo "Selected source URL: $URL_SOURCE"'
    - echo "Determining sha256sum for remote binary..."
    - 'SHA_BIN=$(curl -sSL "$URL_BIN" | sha256sum | cut -d" " -f1)'
    - 'echo "Got sha256sum: $SHA_BIN"'
    - 'SHA_BASH_COMPLETION=$(curl -sSL "$URL_BASH_COMPLETION" | sha256sum | cut -d" " -f1)'
    - 'echo "Got sha256sums of bash completion: $SHA_BASH_COMPLETION"'
    - 'SHA_ZSH_COMPLETION=$(curl -sSL "$URL_ZSH_COMPLETION" | sha256sum | cut -d" " -f1)'
    - 'echo "Got sha256sums of ZSH completion: $SHA_ZSH_COMPLETION"'
    - 'SHA_FISH_COMPLETION=$(curl -sSL "$URL_FISH_COMPLETION" | sha256sum | cut -d" " -f1)'
    - 'echo "Got sha256sums of fish completion: $SHA_FISH_COMPLETION"'
    - 'SHA_LICENSE=$(curl -sSL "$URL_LICENSE" | sha256sum | cut -d" " -f1)'
    - 'echo "Got sha256sums of LICENSE: $SHA_LICENSE"'
    - echo "Determining sha256sum for remote source..."
    - 'SHA_SOURCE=$(curl -sSL "$URL_SOURCE" | sha256sum | cut -d" " -f1)'
    - 'echo "Got sha256sum: $SHA_SOURCE"'

    # Update PKGBUILD parameters: version, source URL and SHA sum
    - echo "Updating PKGBUILDS with release information..."
    - sed "s/^pkgver=.*\$/pkgver=$VERSION/" -i ffsend/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/^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.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.fish::\).*\"/\1$(echo $URL_FISH_COMPLETION | sed 's/\//\\\//g')\"/" -i ffsend-bin/PKGBUILD
    - sed "s/\(\"LICENSE-v\$pkgver::\).*\"/\1$(echo $URL_LICENSE | sed 's/\//\\\//g')\"/" -i ffsend-bin/PKGBUILD
    - sed "s/^sha256sums=.*\$/sha256sums=('$SHA_SOURCE')/" -i ffsend/PKGBUILD
    - sed "s/^sha256sums=.*\$/sha256sums=('$SHA_BIN' '$SHA_BASH_COMPLETION' '$SHA_ZSH_COMPLETION' '$SHA_FISH_COMPLETION' '$SHA_LICENSE')/" -i ffsend-bin/PKGBUILD

    # Get SHA hash for local and remote file w/o version, update if it has changed
    - 'SHA_STRIP_LOCAL=$(cat ffsend-git/PKGBUILD | sed /^pkgver=.\*/d | sha256sum | cut -d" " -f1)'
    - 'SHA_STRIP_REMOTE=$(curl -sSL "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=ffsend-git" | sed /^pkgver=.\*/d | sha256sum | cut -d" " -f1)'

    # Install dependencies
    - echo "Installing required build packages..."
    - pacman -Syu --noconfirm sudo base-devel binutils openssh rust cargo cmake git openssl

    # Make AUR package
    - mkdir -p /.cargo
    - chmod -R 777 /.cargo
    - cd ffsend-bin/
    - echo "Making binary package..."
    - sudo -u nobody makepkg -c
    - sudo -u nobody makepkg --printsrcinfo > .SRCINFO
    - cd ../ffsend
    - echo "Making main source package..."
    - sudo -u nobody makepkg -c
    - sudo -u nobody makepkg --printsrcinfo > .SRCINFO
    # Make git package if different than the remote
    - |
      if [ ! "$SHA_STRIP_LOCAL" == "$SHA_STRIP_REMOTE" ]; then
        cd ../ffsend-git
        echo "Making git source package..."
        sudo -u nobody makepkg -c
        sudo -u nobody makepkg --printsrcinfo > .SRCINFO
      else
        echo "Not making git source package, it has not changed"
      fi
    - cd ..

    # Set up SSH for publishing
    - mkdir -p /root/.ssh
    - cp ./aur.pub /root/.ssh/id_rsa.pub
    - echo "$AUR_SSH_PRIVATE" > /root/.ssh/id_rsa
    - echo "Host aur.archlinux.org" >> /root/.ssh/config
    - echo "  IdentityFile /root/.ssh/aur" >> /root/.ssh/config
    - echo "  User aur" >> /root/.ssh/config
    - chmod 600 /root/.ssh/{id_rsa*,config}
    - eval `ssh-agent -s`
    - ssh-add /root/.ssh/id_rsa
    - ssh-keyscan -H aur.archlinux.org >> /root/.ssh/known_hosts
    - git config --global user.name "timvisee"
    - git config --global user.email "tim@visee.me"

    # Publish main package: clone AUR repo, commit update and push
    - git clone ssh://aur@aur.archlinux.org/ffsend.git aur-ffsend
    - cd aur-ffsend
    - cp ../ffsend/{PKGBUILD,.SRCINFO} ./
    - git add PKGBUILD .SRCINFO
    - git commit -m "Release v$VERSION"
    - git push
    - cd ..

    # Publish binary package: clone AUR repo, commit update and push
    - git clone ssh://aur@aur.archlinux.org/ffsend-bin.git aur-ffsend-bin
    - cd aur-ffsend-bin
    - cp ../ffsend-bin/{PKGBUILD,.SRCINFO} ./
    - git add PKGBUILD .SRCINFO
    - git commit -m "Release v$VERSION"
    - git push
    - cd ..

    # Publish git package: clone AUR repo, commit update and push
    # Only publish it if it is different than the remote
    - |
      if [ ! "$SHA_STRIP_LOCAL" == "$SHA_STRIP_REMOTE" ]; then
        git clone ssh://aur@aur.archlinux.org/ffsend-git.git aur-ffsend-git
        cd aur-ffsend-git
        cp ../ffsend-git/{PKGBUILD,.SRCINFO} ./
        git add PKGBUILD .SRCINFO
        git commit -m "Update PKGBUILD for release v$VERSION"
        git push
        cd ..
      else
        echo "Not pushing git package, it has not changed"
      fi

# TODO: add job to test ffsend{-git} AUR packages


================================================
FILE: .travis.yml
================================================
# Travis CI configuration for building macOS binaries for ffsend.
# These macOS binaries are published on GitHub as release files.
#
# The main CI runs on GitLab CI at: https://gitlab.com/timvisee/ffsend/pipelines

language: rust

# Only build release jobs
stages:
  - name: release
    if: tag =~ ^v(\d+\.)*\d+$

jobs:
  include:
    - stage: release
      rust: stable
      os: osx
      env: RUST_TARGET=x86_64-apple-darwin
      cache: cargo
      script:
        # Create release binary for macOS
        - echo "Creating release binary for $RUST_TARGET..."
        - cargo build --target=$RUST_TARGET --release --verbose --all
        - cp target/$RUST_TARGET/release/ffsend ./ffsend

        # Download github-release binary
        - wget https://github.com/tfausak/github-release/releases/download/1.2.4/github-release-osx.gz -O github-release.gz
        - gunzip github-release.gz
        - chmod a+x ./github-release

        # Create the release, upload binary
        - ./github-release release --token "$GITHUB_TOKEN" --owner timvisee --repo ffsend --tag "$TRAVIS_TAG"  --title "ffsend $TRAVIS_TAG"
        - ./github-release upload --token "$GITHUB_TOKEN" --owner timvisee --repo ffsend --tag "$TRAVIS_TAG" --file ./ffsend --name ffsend-$TRAVIS_TAG-macos

        # TODO: disabled for now to throttle updates, manually enable on major release
        # # Update homebrew package
        # - git config --global user.name "timvisee"
        # - git config --global user.email "$GIT_EMAIL"
        # - git config --global credential.helper store
        # - echo "https://timvisee:$HOMEBREW_GITHUB_API_TOKEN@github.com" >> ~/.git-credentials
        # - brew bump-formula-pr --url="https://github.com/timvisee/ffsend/archive/$TRAVIS_TAG.tar.gz" --message="Automated release pull request using continuous integration." --no-browse -f -v ffsend


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

**Repository:**
- [GitLab repository][gitlab]
- _Mirror: [GitHub repository][github]_

**Issues:** (bug reporting, feature requests, enhancements, etc.)
- [GitLab issue board][gitlab-issues]
- _Alternatively: [GitHub issue board][github-issues]_

**Pull/merge requests:** (fixes, implemented features, etc.)
- [GitLab merge requests][gitlab-mr]
- _Alternatively: [GitHub pull requests][github-pr]_



Contributions to the `ffsend` project are welcome!
When contributing new features, alternative implementations or bigger
improvements, please first discuss the change you wish to make via an issue
or email.
Small changes such as fixed commands, fixed spelling or dependency updates
are always welcome without discussion.

The `ffsend` repository is primarily hosted on [GitLab][gitlab].
[GitHub][github] hosts a mirror, for publicity and findability.
Please open any issues or pull requests on the [GitLab][gitlab] pages if possible.
Otherwise opening these on [GitHub][github] is fine, though they might be
manually moved over to [GitLab][gitlab].

Please note we have a code of conduct, please follow it in all your interactions
with the project.

## Pull Request Process

1. Ensure you've discussed your improvements in an issue when working on a
   bigger change
2. Ensure your branch is up-to-date with the latest [`master`][branch-master]
3. Ensure the project builds with your changes: `cargo build`
4. Ensure the project tests succeed with your changes: `cargo test`
5. Update the `README.md` with details of significant changes, this includes new
   compiler features, command-line arguments, environment variables or new
   package installation instructions.
6. Submit your pull request.
7. Fix any issues continuous integration might report.

Additional notes:
- Do not change version numbers, this is done by @timvisee

## Code of Conduct

### Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.

### Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

### Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

### Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

### Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project owner at 3a4fb3964f@sinenomine.email. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][coc-homepage], version 1.4,
available at [https://contributor-covenant.org/version/1/4][coc-version]

## License
This project is released under the GNU GPL-3.0 license.
Check out the [LICENSE](LICENSE) file for more information.

[branch-master]: https://gitlab.com/timvisee/ffsend/tree/master
[gitlab]: https://gitlab.com/timvisee/ffsend
[gitlab-issues]: https://gitlab.com/timvisee/ffsend/issues
[gitlab-mr]: https://gitlab.com/timvisee/ffsend/merge_requests
[github]: https://github.com/timvisee/ffsend
[github-issues]: https://github.com/timvisee/ffsend/issues
[github-pr]: https://github.com/timvisee/ffsend/pulls
[coc-homepage]: https://contributor-covenant.org
[coc-version]: https://contributor-covenant.org/version/1/4/


================================================
FILE: Cargo.toml
================================================
[package]
name = "ffsend"
version = "0.2.77"
rust-version = "1.63.0"
authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"]
license = "GPL-3.0"
readme = "README.md"
homepage = "https://timvisee.com/projects/ffsend"
repository = "https://gitlab.com/timvisee/ffsend"
description = """\
    Easily and securely share files from the command line.\n\
    A fully featured Send client.\
"""
keywords = ["send", "firefox", "cli"]
categories = [
    "authentication",
    "command-line-interface",
    "command-line-utilities",
    "cryptography",
    "network-programming",
]
exclude = [
    "/.github",
    "/contrib",
    "/pkg",
    "/res",
    "/*.yml",
    "/CONTRIBUTING.md",
    "/SECURITY.md",
]
edition = "2018"
build = "build.rs"

[package.metadata.deb]
section = "utility"
extended-description = """\
Easily and securely share files and directories from the command line through
a safe, private and encrypted link using a single simple command. \
Files are shared using the Send service and may be up to 2GB. \
Others are able to download these files with this tool, \
or through their web browser.\n\
\n\
All files are always encrypted on the client, \
and secrets are never shared with the remote host. \
An optional password may be specified, and a default file lifetime of 1 \
(up to 20) download or 24 hours is enforced to ensure your stuff does not \
remain online forever. This provides a secure platform to share your files."""
priority = "standard"
license-file = ["LICENSE", "3"]
depends = "$auto, libssl1.1, ca-certificates, xclip"
maintainer-scripts = "pkg/deb"

[[bin]]
name = "ffsend"
path = "src/main.rs"

[features]
default = ["archive", "clipboard", "crypto-ring", "history", "infer-command", "qrcode", "send3", "urlshorten"]

# Compile with file archiving support
archive = ["tar"]

# Support for putting share URLs in clipboard
clipboard = ["clip", "which"]

# Compile with file history support
history = []

# Support for Send v2
send2 = ["ffsend-api/send2"]

# Support for Send v3
send3 = ["ffsend-api/send3"]

# Use OpenSSL as cryptography backend
crypto-openssl = ["ffsend-api/crypto-openssl"]

# Use ring as cryptography backend
crypto-ring = ["ffsend-api/crypto-ring"]

# Support for generating QR codes for share URLs
qrcode = ["qr2term"]

# Support for shortening share URLs
urlshorten = ["urlshortener"]

# Support for inferring subcommand when linking binary
infer-command = []

# Compile without colored output support
no-color = ["colored/no-color"]

# Automatic using build.rs: use xclip/xsel binary method for clipboard support
clipboard-bin = ["clipboard"]

# Automatic using build.rs: use native clipboard crate for clipboard support
clipboard-crate = ["clipboard"]

[dependencies]
chbs = "0.1.0"
chrono = "0.4"
clap = "2.33"
colored = "2.0"
derive_builder = "0.10"
directories = "4.0"
failure = "0.1"
ffsend-api = { version = "0.7.3", default-features = false }
fs2 = "0.4"
lazy_static = "1.4"
open = "2"
openssl-probe = "0.1"
pathdiff = "0.2"
pbr = "1"
prettytable-rs = { version = "0.10.0", default-features = false }
qr2term = { version = "0.2", optional = true }
rand = "0.8"
regex = "1.5"
rpassword = "5"
serde = "1"
serde_derive = "1"
tar = { version = "0.4", optional = true }
tempfile = "3"
toml = "0.5"
urlshortener = { version = "3", optional = true }
version-compare = "0.1"

[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 }

[target.'cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd")))'.dependencies]
# Aliased to clip to prevent name collision with clipboard feature
clip = { version = "0.5", optional = true, package = "clipboard" }

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     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>.


================================================
FILE: README.md
================================================
[![Build status on GitLab CI][gitlab-ci-master-badge]][gitlab-ci-link]
[![Newest release on crates.io][crate-version-badge]][crate-link]
[![Project license][crate-license-badge]](LICENSE)

[crate-license-badge]: https://img.shields.io/crates/l/ffsend.svg
[crate-link]: https://crates.io/crates/ffsend
[crate-version-badge]: https://img.shields.io/crates/v/ffsend.svg
[gitlab-ci-link]: https://gitlab.com/timvisee/ffsend/pipelines
[gitlab-ci-master-badge]: https://gitlab.com/timvisee/ffsend/badges/master/pipeline.svg

*Notice: the default Send host is provided by [@timvisee][timvisee]
([info](https://gitlab.com/timvisee/ffsend/-/issues/111)).
Please consider to [donate] and help keep it running.*

# ffsend

> Easily and securely share files from the command line.
> A [Send][send] client.

Easily and securely share files and directories from the command line through a
safe, private and encrypted link using a single simple command.
Files are shared using the [Send][send] service and may be up
to 1GB. Others are able to download these files with this tool, or through
their web browser.

[![ffsend usage demo][usage-demo-svg]][usage-demo-asciinema]  
_No demo visible here? View it on [asciinema][usage-demo-asciinema]._

All files are always encrypted on the client, and secrets are never shared with
the remote host. An optional password may be specified, and a default file
lifetime of 1 (up to 20) download or 24 hours is enforced to ensure your stuff
does not remain online forever.
This provides a secure platform to share your files.
Find out more about security [here](#security).

- [Features](#features)
- [Usage](#usage)
- [Requirements](#requirements)
- [Install](#install) ([Linux](#linux-all-distributions), [macOS](#macos), [Windows](#windows), [FreeBSD](#freebsd), [Android](#android), [_Other OS/architecture_](#other-os-or-architecture))
- [Build](#build)
- [Configuration and environment](#configuration-and-environment)
- [Security](#security)
- [Help](#help)
- [Special thanks](#special-thanks)
- [License](#license)

The public [Send][send] service that is used as default host is provided by
[@timvisee][timvisee] ([info](https://gitlab.com/timvisee/ffsend/-/issues/111)).  
This application is not affiliated with [Firefox][firefox] or
[Mozilla][mozilla] in any way.

_Note: this tool is currently in beta, as some extra desired features are yet to be implemented_

## Features
- Fully featured and friendly command line tool
- Upload and download files and directories securely, always encrypted on the client
- Additional password protection, generation and configurable download limits
- File and directory archiving and extraction
- Built-in share URL shortener and QR code generator
- Supports Send v3 (current) and v2
- History tracking your files for easy management
- Ability to use your own Send hosts
- Inspect or delete shared files
- Accurate error reporting
- Streaming encryption and uploading/downloading, very low memory footprint
- Intended for use in [scripts](#scriptability) without interaction

For a list of upcoming features and ideas, take a look at the
current [open issues](https://gitlab.com/timvisee/ffsend/issues) over on GitLab.

## Usage
Easily upload and download:

```bash
# Simple upload
$ ffsend upload my-file.txt
https://send.vis.ee/#sample-share-url

# Advanced upload
# - Specify a download limit of 1
# - Specify upload expiry time of 5 minutes
# - Enter a password to encrypt the file
# - Archive the file before uploading
# - Copy the shareable link to your clipboard
# - Open the shareable link in your browser
$ ffsend upload --downloads 1 --expiry-time 5m --password --archive --copy --open my-file.txt
Password: ******
https://send.vis.ee/#sample-share-url

# Upload to your own host
$ ffsend u -h https://example.com/ my-file.txt
https://example.com/#sample-share-url

# Simple download
$ ffsend download https://send.vis.ee/#sample-share-url
```

Inspect remote files:

```bash
# Check if a file exists
$ ffsend exists https://send.vis.ee/#sample-share-url
Exists: yes

# Fetch remote file info
$ ffsend info https://send.vis.ee/#sample-share-url
ID:         b087066715
Name:       my-file.txt
Size:       12 KiB
MIME:       text/plain
Downloads:  0 of 10
Expiry:     18h2m (64928s)
```

Other commands include:

```bash
# View your file history
$ ffsend history
#  LINK                                        EXPIRE
1  https://send.vis.ee/#sample-share-url  23h57m
2  https://send.vis.ee/#other-sample-url  17h38m
3  https://example.com/#sample-share-url       37m30s

# Change the password after uploading
$ ffsend password https://send.vis.ee/#sample-share-url
Password: ******

# Delete a file
$ ffsend delete https://send.vis.ee/#sample-share-url
```

Use the `--help` flag, `help` subcommand, or see the [help](#help) section for
all available subcommands.

## Requirements
- Linux, macOS, Windows, FreeBSD, Android (other BSDs might work)
- A terminal :sunglasses:
- Internet connection
- Linux:
  - OpenSSL & CA certificates:
    - Ubuntu, Debian and derivatives: `apt install openssl ca-certificates`
  - Optional: `xclip` or `xsel` for clipboard support
    - Ubuntu, Debian and derivatives: `apt install xclip`
    - CentOS/Red Hat/openSUSE/Fedora: `yum install xclip`
    - Arch: `pacman -S xclip`
- Windows specific:
  - Optional OpenSSL with `crypto-openssl` feature: [» Installer][openssl-windows-installer] (`v1.1.0j` or above)
- macOS specific:
  - Optional OpenSSL with `crypto-openssl` feature: `brew install openssl@1.1`
- FreeBSD specific:
  - OpenSSL: `pkg install openssl`
  - CA certificates: `pkg install ca_root_nss`
  - Optional `xclip` & `xsel` for clipboard support: `pkg install xclip xsel-conrad`
- Android specific:
  - Termux: [» Termux][termux]

## Install
Because `ffsend` is still in early stages, only limited installation options are
available right now. Feel free to contribute additional packages.

Make sure you meet and install the [requirements](#requirements).

See the operating system specific instructions below:
- [Linux](#linux-all-distributions)
- [macOS](#macos)
- [Windows](#windows)
- [FreeBSD](#freebsd)
- [Android](#android)
- [_Other OS or architecture_](#other-os-or-architecture)

### Linux (all distributions)
Using the [snap](#linux-snap-package) package is recommended if supported.  
Alternatively you may install it manually using the
[prebuilt binaries](#linux-prebuilt-binaries).

Only 64-bit (`x86_64`) packages and binaries are provided.
For other architectures and configurations you may [compile from source](#build).

More packages options will be coming soon.

#### Linux: snap package
_Note: The `ffsend` `snap` package is isolated, and can only access files in
your home directory. Choose a different installation option if you don't want
this limitation._

_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
you're experiencing problems, please refer to a different installation method
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]

```bash
snap install ffsend
ffsend --help
```

#### Linux: Arch AUR packages
[» `ffsend-bin`][aur-ffsend-bin] (precompiled binary, latest release, recommended)  
[» `ffsend`][aur-ffsend] (compiles from source, latest release)  
[» `ffsend-git`][aur-ffsend-git] (compiles from source, latest `master` commit)

```bash
yay -S ffsend
# or
aurto add ffsend-bin
sudo pacman -S ffsend-bin
# or using any other AUR helper

ffsend --help
```

#### Linux: Nix package
_Note: The Nix package is currently not automatically updated, and might be
slightly outdated._

[» ffsend][nix-ffsend]

```bash
nix-channel --update
nix-env --install ffsend

ffsend --help
```

#### Linux: Fedora package
_Note: The Fedora package is maintained by contributors, and might be
slightly outdated._

[» ffsend][fedora-ffsend]

```bash
sudo dnf install ffsend

ffsend --help
```

#### Linux: Alpine package
_Note: The Alpine package is maintained by contributors, it might be outdated.
Choose a different installation method if an important update is missing._

[» ffsend][alpine-ffsend]

```bash
apk add ffsend --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing

ffsend --help
```

#### Linux: Prebuilt binaries
Check out the [latest release][github-latest-release] assets for Linux binaries.  
Use the `ffsend-v*-linux-x64-static` binary, to minimize the chance for issues.
If it isn't available yet, you may use an artifact from a
[previous version][github-releases] instead, until it is available.

Make sure you meet and install the [requirements](#requirements) before you
continue.

You must make the binary executable, and may want to move it into `/usr/bin` to
make it easily executable:

```bash
# Rename binary to ffsend
mv ./ffsend-* ./ffsend

# Mark binary as executable
chmod a+x ./ffsend

# Move binary into path, to make it easily usable
sudo mv ./ffsend /usr/local/bin/

ffsend --help
```

### macOS
Using the [`homebrew` package](#macos-homebrew-package) is recommended.  
Alternatively you may install it via [MacPorts](#macos-macports), or manually using the
[prebuilt binaries](#macos-prebuilt-binaries).

#### macOS: homebrew package
Make sure you've [`homebrew`][homebrew] installed, and run:

```bash
brew install ffsend
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
_Note: The Nix package is currently not automatically updated, and might be
slightly outdated._

```bash
nix-channel --update
nix-env --install ffsend

ffsend --help
```

#### macOS: Prebuilt binaries
Check out the [latest release][github-latest-release] assets for a macOS binary.
If it isn't available yet, you may use an artifact from a
[previous version][github-releases] instead, until it is available.

Then, mark the downloaded binary as an executable.
You then may want to move it into `/usr/local/bin/` to make the `ffsend` command
globally available:

```bash
# Rename file to ffsend
mv ./ffsend-* ./ffsend

# Mark binary as executable
chmod a+x ./ffsend

# Move binary into path, to make it easily usable
sudo mv ./ffsend /usr/local/bin/

ffsend
```

### Windows
Using the [`scoop` package](#windows-scoop-package) is recommended.  
Alternatively you may install it manually using the
[prebuilt binaries](#windows-prebuilt-binaries).

If you're using the [Windows Subsystem for Linux][wsl], it's highly recommended
to install the [prebuilt Linux binary](#prebuilt-binaries-for-linux) instead.

Only 64-bit (`x86_64`) binaries are provided.
For other architectures and configurations you may [compile from source](#build).

A `chocolatey` package along with an `.msi` installer will be coming soon.

#### Windows: scoop package
Make sure you've [`scoop`][scoop-install] installed, and run:

```bash
scoop install ffsend
ffsend --help
```

#### Windows: Prebuilt binaries
Check out the [latest release][github-latest-release] assets for Windows binaries.
Use the `ffsend-v*-windows-x64-static` binary, to minimize the chance for issues.
If it isn't available yet, you may use an artifact from a
[previous version][github-releases] instead, until it is available.

You can use `ffsend` from the command line in the same directory:
```cmd
.\ffsend.exe --help
```

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`:
```cmd
move .\ffsend.exe C:\Windows\System32\ffsend.exe
```

### FreeBSD

[» `ffsend`][freshports-ffsend]

_Note: The FreeBSD package is currently maintained by FreeBSD contributors,
and might be slightly outdated._

```sh
# Precompiled binary.
pkg install ffsend

# Compiles and installs from source.
cd /usr/ports/www/ffsend && make install
```

### Android
`ffsend` can be used on Android through Termux, install it first:
[» Termux][termux]

_Note: The Android package is currently maintained by Termux contributors,
and might be slightly outdated._

```sh
# Install package.
pkg install ffsend

ffsend help
```

### Other OS or architecture
If your system runs Docker, you can use the [docker image](#docker-image).
There are currently no other binaries or packages available.

You can [build the project from source](#build) instead.

#### Docker image
A Docker image is available for using `ffsend` running in a container.
Mount a directory to `/data`, so it's accessible for `ffsend` in the container,
and use the command as you normally would.

[» `timvisee/ffsend`][docker-hub-ffsend]

```bash
# Invoke without arguments
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
docker run --rm -it -v $(pwd):/data timvisee/ffsend download https://send.vis.ee/#sample-share-url

# Show help
docker run --rm -it -v $(pwd):/data timvisee/ffsend help

# To update the used image
docker pull timvisee/ffsend
```

On Linux or macOS you might define a alias in your shell configuration, to make
it invocable as `ffsend`:

```bash
alias ffsend='docker run --rm -it -v "$(pwd):/data" timvisee/ffsend'
```

_Note: This implementation is limited to accessing the paths you make available
through the specified mount._

## Build
To build and install `ffsend` yourself, you meet the following requirements
before proceeding:

### Build requirements
- Runtime [requirements](#requirements)
- [`git`][git]
- [`rust`][rust] `v1.63` (MSRV) or higher (install using [`rustup`][rustup])
- [OpenSSL][openssl] or [LibreSSL][libressl] libraries/headers:
  - Linux:
    - Ubuntu, Debian and derivatives: `apt install build-essential cmake pkg-config libssl-dev`
    - CentOS/Red Hat/openSUSE: `yum install gcc gcc-c++ make cmake openssl-devel`
    - Arch: `pacman -S openssl base-devel`
    - Gentoo: `emerge -a dev-util/pkgconfig dev-util/cmake dev-libs/openssl`
    - Fedora: `dnf install gcc gcc-c++ make cmake openssl-devel`
    - Or see instructions [here](https://github.com/sfackler/rust-openssl#linux)
  - Windows:
    - Optional with `crypto-openssl` feature: See instructions here [here](https://github.com/sfackler/rust-openssl#windows-msvc)
  - macOS:
    - Optional with `crypto-openssl` feature: `brew install cmake pkg-config openssl` or see instructions [here](https://github.com/sfackler/rust-openssl#osx)
  - FreeBSD:
    - `pkg install rust gmake pkgconf python36 libxcb xclip ca_root_nss xsel-conrad`
    - It is a better idea to use & modify the existing `ffsend` port, which manages dependencies for you.

### Compile and install
Then, walk through one of the following steps to compile and install `ffsend`:

- Compile and install it directly from cargo:

  ```bash
  # Compile and install from cargo
  cargo install ffsend -f

  # Start using ffsend
  ffsend --help
  ```

- Or clone the repository and install it with `cargo`:

  ```bash
  # Clone the project
  git clone https://github.com/timvisee/ffsend.git
  cd ffsend

  # Compile and install
  cargo install --path . -f

  # Start using ffsend
  ffsend --help

  # or run it directly from cargo
  cargo run --release -- --help
  ```

- Or clone the repository and invoke the binary directly (Linux/macOS):

  ```bash
  # Clone the project
  git clone https://github.com/timvisee/ffsend.git
  cd ffsend

  # Build the project (release version)
  cargo build --release

  # Start using ffsend
  ./target/release/ffsend --help
  ```

### Compile features / use flags
Different use flags are available for `ffsend` to toggle whether to include
various features.
The following features are available, some of which are enabled by default:

| Feature         | Enabled | Description                                                |
| :-------------: | :-----: | :--------------------------------------------------------- |
| `send2`         | Default | Support for Send v2 servers                                |
| `send3`         | Default | Support for Send v3 servers                                |
| `crypto-ring`   | Default | Use ring as cryptography backend                           |
| `crypto-openssl`|         | Use OpenSSL as cryptography backend                        |
| `clipboard`     | Default | Support for copying links to the clipboard                 |
| `history`       | Default | Support for tracking files in history                      |
| `archive`       | Default | Support for archiving and extracting uploads and downloads |
| `qrcode`        | Default | Support for rendering a QR code for a share URL            |
| `urlshorten`    | Default | Support for shortening share URLs                          |
| `infer-command` | Default | Support for inferring subcommand based on binary name      |
| `no-color`      |         | Compile without color support in error and help messages   |

To enable features during building or installation, specify them with
`--features <features...>` when using `cargo`.
You may want to disable default features first using
`--no-default-features`.
Here are some examples:

```bash
# Defaults set of features with no-color, one of
cargo install --features no-color
cargo build --release --features no-color

# No default features, except required
cargo install --no-default-features --features send3,crypto-ring

# With history and clipboard support
cargo install --no-default--features --features send3,crypto-ring,history,clipboard
```

For Windows systems it is recommended to provide the `no-color` flag, as color
support in Windows terminals is flaky.

## Configuration and environment
The following environment variables may be used to configure the following
defaults. The CLI flag is shown along with it, to better describe the relation
to command line arguments:

| Variable                  | CLI flag                       | Description                                   |
| :------------------------ | :----------------------------: | :-------------------------------------------- |
| `FFSEND_HISTORY`          | `--history <FILE>`             | History file path                             |
| `FFSEND_HOST`             | `--host <URL>`                 | Upload host                                   |
| `FFSEND_TIMEOUT`          | `--timeout <SECONDS>`          | Request 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_DOWNLOAD_LIMIT`   | `--download-limit <DOWNLOADS>` | Default download limit                        |
| `FFSEND_API`              | `--api <VERSION>`              | Server API version, `-` to lookup             |
| `FFSEND_BASIC_AUTH`       | `--basic-auth <USER:PASSWORD>` | Basic HTTP authentication credentials to use. |

These environment variables may be used to toggle a flag, simply by making them
available. The actual value of these variables is ignored, and variables may be
empty.

| Variable             | CLI flag        | Description                        |
| :------------------- | :-------------: | :--------------------------------- |
| `FFSEND_FORCE`       | `--force`       | Force operations                   |
| `FFSEND_NO_INTERACT` | `--no-interact` | No interaction for prompts         |
| `FFSEND_YES`         | `--yes`         | Assume yes for prompts             |
| `FFSEND_INCOGNITO`   | `--incognito`   | Incognito mode, don't use history  |
| `FFSEND_OPEN`        | `--open`        | Open share link of uploaded file   |
| `FFSEND_ARCHIVE`     | `--archive`     | Archive files uploaded             |
| `FFSEND_EXTRACT`     | `--extract`     | Extract files downloaded           |
| `FFSEND_COPY`        | `--copy`        | Copy share link to clipboard       |
| `FFSEND_COPY_CMD`    | `--copy-cmd`    | Copy download command to clipboard |
| `FFSEND_QUIET`       | `--quiet`       | Log quiet information              |
| `FFSEND_VERBOSE`     | `--verbose`     | Log verbose information            |

Some environment variables may be set at compile time to tweak some defaults.

| Variable     | Description                                                                |
| :----------- | :------------------------------------------------------------------------- |
| `XCLIP_PATH` | Set fixed `xclip` binary path when using `clipboard-bin` (Linux, &ast;BSD) |
| `XSEL_PATH`  | Set fixed `xsel` binary path when using `clipboard-bin` (Linux, &ast;BSD)  |

At this time, no configuration or _dotfile_ file support is available.
This will be something added in a later release.

### Binary for each subcommand: `ffput`, `ffget`
`ffsend` supports having a separate binaries for single subcommands, such as
having `ffput` and `ffget` just for to upload and download using `ffsend`.
This allows simple and direct commands like:
```bash
ffput my-file.txt
ffget https://send.vis.ee/#sample-share-url
```

This works for a predefined list of binary names:

- `ffput` → `ffsend upload ...`
- `ffget` → `ffsend download ...`
- `ffdel` → `ffsend delete ...`
- _This list is defined in [`src/config.rs`](./src/config.rs) as `INFER_COMMANDS`_

You can use the following methods to set up these single-command binaries:

- Create a properly named symbolic link (recommended)
- Create a properly named hard link
- Clone the `ffsend` binary, and rename it

On Linux and macOS you can use the following command to set up symbolic links in
the current directory:

```bash
ln -s $(which ffsend) ./ffput
ln -s $(which ffsend) ./ffget
```

Support for this feature is only available when `ffsend` is compiled with the
[`infer-command`](#compile-features--use-flags) feature flag.
This is usually enabled by default.
To verify support is available with an existing installation, make sure the
feature is listed when invoking `ffsend debug`.

Note that the `snap` package does currently not support this due to how this
package format works.

### Scriptability
`ffsend` is optimized for use in automated scripts. It provides some specialized
arguments to control `ffsend` without user interaction.

- `--no-interact` (`-I`): do not allow user interaction. For prompts not having
    a default value, the application will quit with an error, unless `--yes`
    or `--force` is provided.
    This should **always** be given when using automated scripting.  
    Example: when uploading a directory, providing this flag will stop the
    archive question prompt form popping up, and will archive the directory as
    default option.
- `--yes` (`-y`): assume the yes option for yes/no prompt by default.  
    Example: when downloading a file that already exists, providing this flag
    will assume yes when asking to overwrite a file.
- `--force` (`-f`): force to continue with the action, skips any warnings that
    would otherwise quit the application.  
    Example: when uploading a file that is too big, providing this flag will
    ignore the file size warning and forcefully continues.
- `--quiet` (`-q`): be quiet, print as little information as possible.  
    Example: when uploading a file, providing this flag will only output the
    final share URL.

Generally speaking, use the following rules when automating:
- Always provide `--no-interact` (`-I`).
- Provide any combination of `--yes` (`-y`) and `--force` (`-f`) for actions you
  want to complete no matter what.
- When passing share URLs along, provide the `--quiet` (`-q`) flag, when
  uploading for example.

These flags can also automatically be set by defining environment variables as
specified here:  
[» Configuration and environment](#configuration-and-environment)

Here are some examples commands in `bash`:

```bash
# Stop on error
set -e

# Upload a file
# -I: no interaction
# -y: assume yes
# -q: quiet output, just return the share link
URL=$(ffsend -Iy upload -q my-file.txt)

# Render file information
# -I: no interaction
# -f: force, just show the info
ffsend -If info $URL

# Set a password for the uploaded file
ffsend -I password $URL --password="secret"

# Use the following flags automatically from now on
# -I: no interaction
# -f: force
# -y: yes
export FFSEND_NO_INTERACT=1 FFSEND_FORCE=1 FFSEND_YES=1

# Download the uploaded file, overwriting the local variant due to variables
ffsend download $URL --password="secret"
```

For more information on these arguments, invoke `ffsend help` and check out:
[» Configuration and environment](#configuration-and-environment)

For other questions regarding automation or feature requests, be sure to
[open](https://github.com/timvisee/ffsend/issues/) an issue.

## Security
In short; the `ffsend` tool and the [Send][send] service can be considered
secure, and may be used to share sensitive files. Note though that the
created share link for an upload will allow anyone to download the file.
Make sure you don't share this link with unauthorized people.

For more detailed information on encryption, please read the rest of the
paragraphs in this security section.

_Note: even though the encryption method is considered secure, this `ffsend`
tool does not provide any warranty in any way, shape or form for files that
somehow got decrypted without proper authorization._

#### Client side encryption
`ffsend` uses client side encryption, to ensure your files are securely
encrypted before they are uploaded to the remote host. This makes it impossible
for third parties to decrypt your file without having the secret (encryption
key). The file and its metadata are encrypted using `128-bit AES-GCM`, and a
`HMAC SHA-256` signing key is used for request authentication.
This is consistent with the encryption documentation provided by the
[Send][send] service, `ffsend` is a tool for.

A detailed list on the encryption/decryption steps, and on what encryption is
exactly used can be found [here][send-encryption] in the official service
documentation.

#### Note on share link security
The encryption secret, that is used to decrypt the file when downloading,
is included in the share URL behind the `#` (hash). This secret is never sent
the remote server directly when using the share link in your browser.
It would be possible however for a webpage to load some malicious JavaScript
snippet that eventually steals the secret from the link once the page is loaded.
Although this scenario is extremely unlikely, there are some options to prevent
this from happening:

- Only use this `ffsend` tool, do not use the share link in your browser.
- Add additional protection by specifying a password using `--password` while
  uploading, or using the `password` subcommand afterwards.
- Host a secure [Send][send] service instance yourself.

A complete overview on encryption can be found in the official service
documentation [here][send-encryption].

## Help
```
$ ffsend help

ffsend 0.2.72
Tim Visee <3a4fb3964f@sinenomine.email>
Easily and securely share files from the command line.
A fully featured Send client.

The default public Send host is provided by Tim Visee, @timvisee.
Please consider to donate and help keep it running: https://vis.ee/donate

USAGE:
    ffsend [FLAGS] [OPTIONS] [SUBCOMMAND]

FLAGS:
    -f, --force          Force the action, ignore warnings
    -h, --help           Prints help information
    -i, --incognito      Don't update local history for actions
    -I, --no-interact    Not interactive, do not prompt
    -q, --quiet          Produce output suitable for logging and automation
    -V, --version        Prints version information
    -v, --verbose        Enable verbose information and logging
    -y, --yes            Assume yes for prompts

OPTIONS:
    -A, --api <VERSION>                 Server API version to use, '-' to lookup [env: FFSEND_API]
        --basic-auth <USER:PASSWORD>    Protected proxy HTTP basic authentication credentials (not FxA) [env: FFSEND_BASIC_AUTH]
    -H, --history <FILE>                Use the specified history file [env: FFSEND_HISTORY]
    -t, --timeout <SECONDS>             Request timeout (0 to disable) [env: FFSEND_TIMEOUT]
    -T, --transfer-timeout <SECONDS>    Transfer timeout (0 to disable) [env: FFSEND_TRANSFER_TIMEOUT]

SUBCOMMANDS:
    upload        Upload files [aliases: u, up]
    download      Download files [aliases: d, down]
    debug         View debug information [aliases: dbg]
    delete        Delete a shared file [aliases: del, rm]
    exists        Check whether a remote file exists [aliases: e]
    generate      Generate assets [aliases: gen]
    help          Prints this message or the help of the given subcommand(s)
    history       View file history [aliases: h]
    info          Fetch info about a shared file [aliases: i]
    parameters    Change parameters of a shared file [aliases: params]
    password      Change the password of a shared file [aliases: pass, p]
    version       Determine the Send server version [aliases: v]

This application is not affiliated with Firefox or Mozilla.
```

## Special thanks
- to all `ffsend` source/package contributors
- 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
  providing tools to make great visual demos
- to everyone involved in all crate dependencies used

## License
This project is released under the GNU GPL-3.0 license.
Check out the [LICENSE](LICENSE) file for more information.

[usage-demo-asciinema]: https://asciinema.org/a/182225
[usage-demo-svg]: https://cdn.rawgit.com/timvisee/ffsend/6e8ef55b/res/demo.svg
[firefox]: https://firefox.com/
[git]: https://git-scm.com/
[libressl]: https://libressl.org/
[mozilla]: https://mozilla.org/
[openssl]: https://www.openssl.org/
[openssl-windows-installer]: https://u.visee.me/dl/openssl/Win64OpenSSL_Light-1_1_0j.exe
[termux]: https://termux.com/
[rust]: https://rust-lang.org/
[rustup]: https://rustup.rs/
[send]: https://github.com/timvisee/send
[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/
[svg-term]: https://github.com/marionebl/svg-term-cli
[github-releases]: https://github.com/timvisee/ffsend/releases
[github-latest-release]: https://github.com/timvisee/ffsend/releases/latest
[nix-ffsend]: https://nixos.org/nixos/packages.html?attr=ffsend&channel=nixos-unstable&query=ffsend
[fedora-ffsend]: https://src.fedoraproject.org/rpms/rust-ffsend
[aur-ffsend]: https://aur.archlinux.org/packages/ffsend/
[aur-ffsend-bin]: https://aur.archlinux.org/packages/ffsend-bin/
[aur-ffsend-git]: https://aur.archlinux.org/packages/ffsend-git/
[alpine-ffsend]: https://pkgs.alpinelinux.org/packages?name=ffsend&branch=edge
[snapcraft-ffsend]: https://snapcraft.io/ffsend
[homebrew]: https://brew.sh/
[wsl]: https://docs.microsoft.com/en-us/windows/wsl/install-win10
[docker-hub-ffsend]: https://hub.docker.com/r/timvisee/ffsend
[scoop-install]: https://scoop.sh/#installs-in-seconds
[freshports-ffsend]: https://www.freshports.org/www/ffsend
[timvisee]: https://timvisee.com/
[donate]: https://timvisee.com/donate


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

| Version | Supported          |
| ------- | ------------------ |
| 0.2.x   | :white_check_mark: |

## Reporting a Vulnerability

To report a vulnerability in this project, or in one if it's dependency;
please [open](https://gitlab.com/timvisee/ffsend/issues/new) a new issue
on GitLab (or on [GitHub](https://github.com/timvisee/ffsend/issues/new)) describing the situation.

For confidential issues, you may send an email to the main developer (@timvisee) at: `3a4fb3964f@sinenomine.email`  
Or see other methods of contacting over on: [timvisee.com/contact](https://timvisee.com/contact)

To contribute code for fixing a vulnerability, please refer to the [contribution](./CONTRIBUTING.md) document.


================================================
FILE: appveyor.yml
================================================
# AppVeyor CI configuration for building Windows binaries for ffsend.
# These Windows binaries are published on GitHub as release files.
#
# The main CI runs on GitLab CI at: https://gitlab.com/timvisee/ffsend/pipelines

# Only build version tags
skip_non_tags: true
branches:
  only:
    - /v\d*\.\d*\.\d*/

# Build for the x86_64 Windows target
platform: x64
environment:
  RUSTUP_USE_HYPER: 1
  CARGO_HTTP_CHECK_REVOKE: false
  GITHUB_TOKEN:
    secure: jqZ4q5oOthKX/pBL1tRsBJsfGPIee3q+N/UBSCZNjCrlFUNfQSfibBPzzICYg1he
  CHOCOLATEY_TOKEN:
    secure: k5Q57xoXa6qSFScSpRaww2puW0yjYoH19uIq3qS1emOG+lNs9TYCnWYhUzQ2gzfc

  matrix:
    - TARGET: x86_64-pc-windows-msvc
      BITS: 64

# Extract release binary artifacts
artifacts:
- path: .\ffsend*.exe
- path: .\ffsend.*.nupkg

# Install dependencies: Rust
install:
  # Install Rust
  - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
  - rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain stable
  - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
  - rustc -V
  - cargo -V
  - git submodule update --init

# Build dynamic and static Windows binaries, release on GitHub
build_script:
  # Build dynamic release binary
  - cargo build --release --features no-color --verbose
  - copy .\target\release\ffsend.exe .\ffsend-%TARGET%.exe

  # Build static release binary
  - set RUSTFLAGS=-Ctarget-feature=+crt-static
  - cargo build --release --features no-color --verbose
  - copy .\target\release\ffsend.exe .\ffsend-%TARGET%-static.exe

  # Install github-release
  - appveyor DownloadFile https://github.com/tfausak/github-release/releases/download/1.2.4/github-release-windows.zip -FileName github-release.zip
  - 7z e github-release.zip

  # Collect binary, set package version and build chocolatey package
  - copy .\ffsend-%TARGET%-static.exe .\pkg\choco\ffsend\tools\ffsend.exe
  - cd .\pkg\choco\ffsend\
  - ps: echo $env:APPVEYOR_REPO_TAG_NAME
  - ps: ((Get-Content -path .\ffsend.nuspec -Raw) -replace "0.0.0",$env:APPVEYOR_REPO_TAG_NAME.Substring(1)) | Set-Content -Path .\ffsend.nuspec
  - choco pack
  - copy ffsend.*.nupkg ..\..\..\
  - cd ..\..\..\

  # Create the release, upload the binaries
  # TODO: fix the line below, which is causing CI to error
  # - ps: Invoke-Expression -Command '$ErrorActionPreference = "SilentlyContinue"; .\github-release.exe release --token $env:GITHUB_TOKEN --owner timvisee --repo ffsend --tag $env:APPVEYOR_REPO_TAG_NAME --title "ffsend $env:APPVEYOR_REPO_TAG_NAME"; exit 0'
  - ps: .\github-release.exe upload --token $env:GITHUB_TOKEN --owner timvisee --repo ffsend --tag $env:APPVEYOR_REPO_TAG_NAME --file .\ffsend-$env:TARGET.exe --name ffsend-$env:APPVEYOR_REPO_TAG_NAME-windows-x64.exe
  - ps: .\github-release.exe upload --token $env:GITHUB_TOKEN --owner timvisee --repo ffsend --tag $env:APPVEYOR_REPO_TAG_NAME --file .\ffsend-$env:TARGET-static.exe --name ffsend-$env:APPVEYOR_REPO_TAG_NAME-windows-x64-static.exe
  - ps: .\github-release.exe upload --token $env:GITHUB_TOKEN --owner timvisee --repo ffsend --tag $env:APPVEYOR_REPO_TAG_NAME --file (Get-Item .\ffsend.*.nupkg).FullName --name ffsend-$env:APPVEYOR_REPO_TAG_NAME.nupkg

  # Publish the chocolatey package
  # TODO: re-enable when chocolatey is properly accepting packages again
  # - cd .\pkg\choco\ffsend\
  # - choco push --api-key %CHOCOLATEY_TOKEN%
  # - cd ..\..\..\

# We don't test anything here
test: false


================================================
FILE: build.rs
================================================
fn main() {
    #[cfg(all(
        feature = "clipboard",
        any(
            target_os = "linux",
            target_os = "freebsd",
            target_os = "dragonfly",
            target_os = "openbsd",
            target_os = "netbsd",
        )
    ))]
    {
        // Select clipboard binary method
        #[cfg(not(feature = "clipboard-crate"))]
        println!("cargo:rustc-cfg=feature=\"clipboard-bin\"");

        // xclip and xsel paths are inserted at compile time
        println!("cargo:rerun-if-env-changed=XCLIP_PATH");
        println!("cargo:rerun-if-env-changed=XSEL_PATH");
    }

    #[cfg(all(
        feature = "clipboard",
        not(any(
            target_os = "linux",
            target_os = "freebsd",
            target_os = "dragonfly",
            target_os = "openbsd",
            target_os = "netbsd",
        ))
    ))]
    {
        // Select clipboard crate method
        #[cfg(not(feature = "clipboard-bin"))]
        println!("cargo:rustc-cfg=feature=\"clipboard-crate\"");
    }
}


================================================
FILE: contrib/completions/_ffsend
================================================
#compdef ffsend

autoload -U is-at-least

_ffsend() {
    typeset -A opt_args
    typeset -a _arguments_options
    local ret=1

    if is-at-least 5.2; then
        _arguments_options=(-s -S -C)
    else
        _arguments_options=(-s -C)
    fi

    local context curcontext="$curcontext" state line
    _arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
":: :_ffsend_commands" \
"*::: :->ffsend" \
&& ret=0
    case $state in
    (ffsend)
        words=($line[1] "${words[@]}")
        (( CURRENT += 1 ))
        curcontext="${curcontext%:*:*}:ffsend-command-$line[1]:"
        case $line[1] in
            (dbg)
_arguments "${_arguments_options[@]}" \
'-h+[The remote host to upload to]' \
'--host=[The remote host to upload to]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
(debug)
_arguments "${_arguments_options[@]}" \
'-h+[The remote host to upload to]' \
'--host=[The remote host to upload to]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
(del)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(rm)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(delete)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(d)
_arguments "${_arguments_options[@]}" \
'-p+[Unlock a password protected file]' \
'--password=[Unlock a password protected file]' \
'-o+[Output file or directory]' \
'--output=[Output file or directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-e[Extract an archived file]' \
'--extract[Extract an archived file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(down)
_arguments "${_arguments_options[@]}" \
'-p+[Unlock a password protected file]' \
'--password=[Unlock a password protected file]' \
'-o+[Output file or directory]' \
'--output=[Output file or directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-e[Extract an archived file]' \
'--extract[Extract an archived file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(download)
_arguments "${_arguments_options[@]}" \
'-p+[Unlock a password protected file]' \
'--password=[Unlock a password protected file]' \
'-o+[Output file or directory]' \
'--output=[Output file or directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-e[Extract an archived file]' \
'--extract[Extract an archived file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(e)
_arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(exist)
_arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(exists)
_arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(gen)
_arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
":: :_ffsend__generate_commands" \
"*::: :->generate" \
&& ret=0
case $state in
    (generate)
        words=($line[1] "${words[@]}")
        (( CURRENT += 1 ))
        curcontext="${curcontext%:*:*}:ffsend-generate-command-$line[1]:"
        case $line[1] in
            (completion)
_arguments "${_arguments_options[@]}" \
'-o+[Shell completion files output directory]' \
'--output=[Shell completion files output directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':SHELL -- Shell type to generate completions for:(all zsh bash fish powershell elvish)' \
&& ret=0
;;
(complete)
_arguments "${_arguments_options[@]}" \
'-o+[Shell completion files output directory]' \
'--output=[Shell completion files output directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':SHELL -- Shell type to generate completions for:(all zsh bash fish powershell elvish)' \
&& ret=0
;;
(completions)
_arguments "${_arguments_options[@]}" \
'-o+[Shell completion files output directory]' \
'--output=[Shell completion files output directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':SHELL -- Shell type to generate completions for:(all zsh bash fish powershell elvish)' \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
        esac
    ;;
esac
;;
(generate)
_arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
":: :_ffsend__generate_commands" \
"*::: :->generate" \
&& ret=0
case $state in
    (generate)
        words=($line[1] "${words[@]}")
        (( CURRENT += 1 ))
        curcontext="${curcontext%:*:*}:ffsend-generate-command-$line[1]:"
        case $line[1] in
            (completion)
_arguments "${_arguments_options[@]}" \
'-o+[Shell completion files output directory]' \
'--output=[Shell completion files output directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':SHELL -- Shell type to generate completions for:(all zsh bash fish powershell elvish)' \
&& ret=0
;;
(complete)
_arguments "${_arguments_options[@]}" \
'-o+[Shell completion files output directory]' \
'--output=[Shell completion files output directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':SHELL -- Shell type to generate completions for:(all zsh bash fish powershell elvish)' \
&& ret=0
;;
(completions)
_arguments "${_arguments_options[@]}" \
'-o+[Shell completion files output directory]' \
'--output=[Shell completion files output directory]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':SHELL -- Shell type to generate completions for:(all zsh bash fish powershell elvish)' \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
        esac
    ;;
esac
;;
(i)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-p+[Unlock a password protected file]' \
'--password=[Unlock a password protected file]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(information)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-p+[Unlock a password protected file]' \
'--password=[Unlock a password protected file]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(info)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-p+[Unlock a password protected file]' \
'--password=[Unlock a password protected file]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(params)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-d+[The file download limit]' \
'--download-limit=[The file download limit]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(param)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-d+[The file download limit]' \
'--download-limit=[The file download limit]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(parameter)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-d+[The file download limit]' \
'--download-limit=[The file download limit]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(parameters)
_arguments "${_arguments_options[@]}" \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-d+[The file download limit]' \
'--download-limit=[The file download limit]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(pass)
_arguments "${_arguments_options[@]}" \
'-p+[Specify a password, do not prompt]' \
'--password=[Specify a password, do not prompt]' \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'(-p --password)-P[Protect the file with a generated passphrase]' \
'(-p --password)--gen-passphrase[Protect the file with a generated passphrase]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(p)
_arguments "${_arguments_options[@]}" \
'-p+[Specify a password, do not prompt]' \
'--password=[Specify a password, do not prompt]' \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'(-p --password)-P[Protect the file with a generated passphrase]' \
'(-p --password)--gen-passphrase[Protect the file with a generated passphrase]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(password)
_arguments "${_arguments_options[@]}" \
'-p+[Specify a password, do not prompt]' \
'--password=[Specify a password, do not prompt]' \
'-o+[Specify the file owner token]' \
'--owner=[Specify the file owner token]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'(-p --password)-P[Protect the file with a generated passphrase]' \
'(-p --password)--gen-passphrase[Protect the file with a generated passphrase]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':URL -- The share URL:_files' \
&& ret=0
;;
(u)
_arguments "${_arguments_options[@]}" \
'-p+[Protect the file with a password]' \
'--password=[Protect the file with a password]' \
'-d+[The file download limit]' \
'--download-limit=[The file download limit]' \
'-e+[The file expiry time]' \
'--expiry-time=[The file expiry time]' \
'-h+[The remote host to upload to]' \
'--host=[The remote host to upload to]' \
'-n+[Rename the file being uploaded]' \
'--name=[Rename the file being uploaded]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'(-p --password)-P[Protect the file with a generated passphrase]' \
'(-p --password)--gen-passphrase[Protect the file with a generated passphrase]' \
'-o[Open the share link in your browser]' \
'--open[Open the share link in your browser]' \
'-D[Delete local file after upload]' \
'--delete[Delete local file after upload]' \
'-a[Archive the upload in a single file]' \
'--archive[Archive the upload in a single file]' \
'(-C --copy-cmd)-c[Copy the share link to your clipboard]' \
'(-C --copy-cmd)--copy[Copy the share link to your clipboard]' \
'(-c --copy)-C[Copy the ffsend download command to your clipboard]' \
'(-c --copy)--copy-cmd[Copy the ffsend download command to your clipboard]' \
'-S[Shorten share URLs with a public service]' \
'--shorten[Shorten share URLs with a public service]' \
'-Q[Print a QR code for the share URL]' \
'--qrcode[Print a QR code for the share URL]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':FILE -- The file(s) to upload:_files' \
&& ret=0
;;
(up)
_arguments "${_arguments_options[@]}" \
'-p+[Protect the file with a password]' \
'--password=[Protect the file with a password]' \
'-d+[The file download limit]' \
'--download-limit=[The file download limit]' \
'-e+[The file expiry time]' \
'--expiry-time=[The file expiry time]' \
'-h+[The remote host to upload to]' \
'--host=[The remote host to upload to]' \
'-n+[Rename the file being uploaded]' \
'--name=[Rename the file being uploaded]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'(-p --password)-P[Protect the file with a generated passphrase]' \
'(-p --password)--gen-passphrase[Protect the file with a generated passphrase]' \
'-o[Open the share link in your browser]' \
'--open[Open the share link in your browser]' \
'-D[Delete local file after upload]' \
'--delete[Delete local file after upload]' \
'-a[Archive the upload in a single file]' \
'--archive[Archive the upload in a single file]' \
'(-C --copy-cmd)-c[Copy the share link to your clipboard]' \
'(-C --copy-cmd)--copy[Copy the share link to your clipboard]' \
'(-c --copy)-C[Copy the ffsend download command to your clipboard]' \
'(-c --copy)--copy-cmd[Copy the ffsend download command to your clipboard]' \
'-S[Shorten share URLs with a public service]' \
'--shorten[Shorten share URLs with a public service]' \
'-Q[Print a QR code for the share URL]' \
'--qrcode[Print a QR code for the share URL]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':FILE -- The file(s) to upload:_files' \
&& ret=0
;;
(upload)
_arguments "${_arguments_options[@]}" \
'-p+[Protect the file with a password]' \
'--password=[Protect the file with a password]' \
'-d+[The file download limit]' \
'--download-limit=[The file download limit]' \
'-e+[The file expiry time]' \
'--expiry-time=[The file expiry time]' \
'-h+[The remote host to upload to]' \
'--host=[The remote host to upload to]' \
'-n+[Rename the file being uploaded]' \
'--name=[Rename the file being uploaded]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'(-p --password)-P[Protect the file with a generated passphrase]' \
'(-p --password)--gen-passphrase[Protect the file with a generated passphrase]' \
'-o[Open the share link in your browser]' \
'--open[Open the share link in your browser]' \
'-D[Delete local file after upload]' \
'--delete[Delete local file after upload]' \
'-a[Archive the upload in a single file]' \
'--archive[Archive the upload in a single file]' \
'(-C --copy-cmd)-c[Copy the share link to your clipboard]' \
'(-C --copy-cmd)--copy[Copy the share link to your clipboard]' \
'(-c --copy)-C[Copy the ffsend download command to your clipboard]' \
'(-c --copy)--copy-cmd[Copy the ffsend download command to your clipboard]' \
'-S[Shorten share URLs with a public service]' \
'--shorten[Shorten share URLs with a public service]' \
'-Q[Print a QR code for the share URL]' \
'--qrcode[Print a QR code for the share URL]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
':FILE -- The file(s) to upload:_files' \
&& ret=0
;;
(ver)
_arguments "${_arguments_options[@]}" \
'-h+[The remote host to upload to]' \
'--host=[The remote host to upload to]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
(v)
_arguments "${_arguments_options[@]}" \
'-h+[The remote host to upload to]' \
'--host=[The remote host to upload to]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
(version)
_arguments "${_arguments_options[@]}" \
'-h+[The remote host to upload to]' \
'--host=[The remote host to upload to]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
(h)
_arguments "${_arguments_options[@]}" \
'-R+[Remove history entry]' \
'--rm=[Remove history entry]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-C[Clear all history]' \
'--clear[Clear all history]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
(ls)
_arguments "${_arguments_options[@]}" \
'-R+[Remove history entry]' \
'--rm=[Remove history entry]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-C[Clear all history]' \
'--clear[Clear all history]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
(history)
_arguments "${_arguments_options[@]}" \
'-R+[Remove history entry]' \
'--rm=[Remove history entry]' \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-C[Clear all history]' \
'--clear[Clear all history]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" \
'-t+[Request timeout (0 to disable)]' \
'--timeout=[Request timeout (0 to disable)]' \
'-T+[Transfer timeout (0 to disable)]' \
'--transfer-timeout=[Transfer timeout (0 to disable)]' \
'-A+[Server API version to use, '\''-'\'' to lookup]' \
'--api=[Server API version to use, '\''-'\'' to lookup]' \
'--basic-auth=[Protected proxy HTTP basic authentication credentials (not FxA)]' \
'-H+[Use the specified history file]' \
'--history=[Use the specified history file]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
'-f[Force the action, ignore warnings]' \
'--force[Force the action, ignore warnings]' \
'-I[Not interactive, do not prompt]' \
'--no-interact[Not interactive, do not prompt]' \
'-y[Assume yes for prompts]' \
'--yes[Assume yes for prompts]' \
'-q[Produce output suitable for logging and automation]' \
'--quiet[Produce output suitable for logging and automation]' \
'*-v[Enable verbose information and logging]' \
'*--verbose[Enable verbose information and logging]' \
'-i[Don'\''t update local history for actions]' \
'--incognito[Don'\''t update local history for actions]' \
&& ret=0
;;
        esac
    ;;
esac
}

(( $+functions[_ffsend_commands] )) ||
_ffsend_commands() {
    local commands; commands=(
        "debug:View debug information" \
"dbg:View debug information" \
"delete:Delete a shared file" \
"del:Delete a shared file" \
"rm:Delete a shared file" \
"download:Download files" \
"d:Download files" \
"down:Download files" \
"exists:Check whether a remote file exists" \
"e:Check whether a remote file exists" \
"generate:Generate assets" \
"gen:Generate assets" \
"info:Fetch info about a shared file" \
"i:Fetch info about a shared file" \
"parameters:Change parameters of a shared file" \
"params:Change parameters of a shared file" \
"password:Change the password of a shared file" \
"pass:Change the password of a shared file" \
"p:Change the password of a shared file" \
"upload:Upload files" \
"u:Upload files" \
"up:Upload files" \
"version:Determine the Send server version" \
"v:Determine the Send server version" \
"history:View file history" \
"h:View file history" \
"help:Prints this message or the help of the given subcommand(s)" \
    )
    _describe -t commands 'ffsend commands' commands "$@"
}
(( $+functions[_ffsend__complete_commands] )) ||
_ffsend__complete_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend complete commands' commands "$@"
}
(( $+functions[_ffsend__generate__complete_commands] )) ||
_ffsend__generate__complete_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend generate complete commands' commands "$@"
}
(( $+functions[_ffsend__completion_commands] )) ||
_ffsend__completion_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend completion commands' commands "$@"
}
(( $+functions[_ffsend__generate__completion_commands] )) ||
_ffsend__generate__completion_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend generate completion commands' commands "$@"
}
(( $+functions[_ffsend__generate__completions_commands] )) ||
_ffsend__generate__completions_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend generate completions commands' commands "$@"
}
(( $+functions[_d_commands] )) ||
_d_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'd commands' commands "$@"
}
(( $+functions[_ffsend__d_commands] )) ||
_ffsend__d_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend d commands' commands "$@"
}
(( $+functions[_dbg_commands] )) ||
_dbg_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'dbg commands' commands "$@"
}
(( $+functions[_ffsend__dbg_commands] )) ||
_ffsend__dbg_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend dbg commands' commands "$@"
}
(( $+functions[_ffsend__debug_commands] )) ||
_ffsend__debug_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend debug commands' commands "$@"
}
(( $+functions[_del_commands] )) ||
_del_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'del commands' commands "$@"
}
(( $+functions[_ffsend__del_commands] )) ||
_ffsend__del_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend del commands' commands "$@"
}
(( $+functions[_ffsend__delete_commands] )) ||
_ffsend__delete_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend delete commands' commands "$@"
}
(( $+functions[_down_commands] )) ||
_down_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'down commands' commands "$@"
}
(( $+functions[_ffsend__down_commands] )) ||
_ffsend__down_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend down commands' commands "$@"
}
(( $+functions[_ffsend__download_commands] )) ||
_ffsend__download_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend download commands' commands "$@"
}
(( $+functions[_e_commands] )) ||
_e_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'e commands' commands "$@"
}
(( $+functions[_ffsend__e_commands] )) ||
_ffsend__e_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend e commands' commands "$@"
}
(( $+functions[_exist_commands] )) ||
_exist_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'exist commands' commands "$@"
}
(( $+functions[_ffsend__exist_commands] )) ||
_ffsend__exist_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend exist commands' commands "$@"
}
(( $+functions[_ffsend__exists_commands] )) ||
_ffsend__exists_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend exists commands' commands "$@"
}
(( $+functions[_gen_commands] )) ||
_gen_commands() {
    local commands; commands=(
        "completions:Shell completions" \
"help:Prints this message or the help of the given subcommand(s)" \
    )
    _describe -t commands 'gen commands' commands "$@"
}
(( $+functions[_ffsend__generate_commands] )) ||
_ffsend__generate_commands() {
    local commands; commands=(
        "completions:Shell completions" \
"help:Prints this message or the help of the given subcommand(s)" \
    )
    _describe -t commands 'ffsend generate commands' commands "$@"
}
(( $+functions[_ffsend__h_commands] )) ||
_ffsend__h_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend h commands' commands "$@"
}
(( $+functions[_h_commands] )) ||
_h_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'h commands' commands "$@"
}
(( $+functions[_ffsend__generate__help_commands] )) ||
_ffsend__generate__help_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend generate help commands' commands "$@"
}
(( $+functions[_ffsend__help_commands] )) ||
_ffsend__help_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend help commands' commands "$@"
}
(( $+functions[_ffsend__history_commands] )) ||
_ffsend__history_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend history commands' commands "$@"
}
(( $+functions[_ffsend__i_commands] )) ||
_ffsend__i_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend i commands' commands "$@"
}
(( $+functions[_i_commands] )) ||
_i_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'i commands' commands "$@"
}
(( $+functions[_ffsend__info_commands] )) ||
_ffsend__info_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend info commands' commands "$@"
}
(( $+functions[_ffsend__information_commands] )) ||
_ffsend__information_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend information commands' commands "$@"
}
(( $+functions[_information_commands] )) ||
_information_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'information commands' commands "$@"
}
(( $+functions[_ffsend__ls_commands] )) ||
_ffsend__ls_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend ls commands' commands "$@"
}
(( $+functions[_ls_commands] )) ||
_ls_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ls commands' commands "$@"
}
(( $+functions[_ffsend__p_commands] )) ||
_ffsend__p_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend p commands' commands "$@"
}
(( $+functions[_p_commands] )) ||
_p_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'p commands' commands "$@"
}
(( $+functions[_ffsend__param_commands] )) ||
_ffsend__param_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend param commands' commands "$@"
}
(( $+functions[_param_commands] )) ||
_param_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'param commands' commands "$@"
}
(( $+functions[_ffsend__parameter_commands] )) ||
_ffsend__parameter_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend parameter commands' commands "$@"
}
(( $+functions[_parameter_commands] )) ||
_parameter_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'parameter commands' commands "$@"
}
(( $+functions[_ffsend__parameters_commands] )) ||
_ffsend__parameters_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend parameters commands' commands "$@"
}
(( $+functions[_ffsend__params_commands] )) ||
_ffsend__params_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend params commands' commands "$@"
}
(( $+functions[_params_commands] )) ||
_params_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'params commands' commands "$@"
}
(( $+functions[_ffsend__pass_commands] )) ||
_ffsend__pass_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend pass commands' commands "$@"
}
(( $+functions[_pass_commands] )) ||
_pass_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'pass commands' commands "$@"
}
(( $+functions[_ffsend__password_commands] )) ||
_ffsend__password_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend password commands' commands "$@"
}
(( $+functions[_ffsend__rm_commands] )) ||
_ffsend__rm_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend rm commands' commands "$@"
}
(( $+functions[_rm_commands] )) ||
_rm_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'rm commands' commands "$@"
}
(( $+functions[_ffsend__u_commands] )) ||
_ffsend__u_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend u commands' commands "$@"
}
(( $+functions[_u_commands] )) ||
_u_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'u commands' commands "$@"
}
(( $+functions[_ffsend__up_commands] )) ||
_ffsend__up_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend up commands' commands "$@"
}
(( $+functions[_up_commands] )) ||
_up_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'up commands' commands "$@"
}
(( $+functions[_ffsend__upload_commands] )) ||
_ffsend__upload_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend upload commands' commands "$@"
}
(( $+functions[_ffsend__v_commands] )) ||
_ffsend__v_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend v commands' commands "$@"
}
(( $+functions[_v_commands] )) ||
_v_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'v commands' commands "$@"
}
(( $+functions[_ffsend__ver_commands] )) ||
_ffsend__ver_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend ver commands' commands "$@"
}
(( $+functions[_ver_commands] )) ||
_ver_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ver commands' commands "$@"
}
(( $+functions[_ffsend__version_commands] )) ||
_ffsend__version_commands() {
    local commands; commands=(
        
    )
    _describe -t commands 'ffsend version commands' commands "$@"
}

_ffsend "$@"

================================================
FILE: contrib/completions/_ffsend.ps1
================================================

using namespace System.Management.Automation
using namespace System.Management.Automation.Language

Register-ArgumentCompleter -Native -CommandName 'ffsend' -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)

    $commandElements = $commandAst.CommandElements
    $command = @(
        'ffsend'
        for ($i = 1; $i -lt $commandElements.Count; $i++) {
            $element = $commandElements[$i]
            if ($element -isnot [StringConstantExpressionAst] -or
                $element.StringConstantType -ne [StringConstantType]::BareWord -or
                $element.Value.StartsWith('-')) {
                break
        }
        $element.Value
    }) -join ';'

    $completions = @(switch ($command) {
        'ffsend' {
            [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('--timeout', 'timeout', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('--transfer-timeout', 'transfer-timeout', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--api', 'api', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--basic-auth', 'basic-auth', [CompletionResultType]::ParameterName, 'Protected proxy HTTP basic authentication credentials (not FxA)')
            [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('--history', 'history', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('--force', 'force', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('-I', 'I', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('--no-interact', 'no-interact', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('-y', 'y', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('-q', 'q', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('--quiet', 'quiet', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            [CompletionResult]::new('--incognito', 'incognito', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('debug', 'debug', [CompletionResultType]::ParameterValue, 'View debug information')
            [CompletionResult]::new('delete', 'delete', [CompletionResultType]::ParameterValue, 'Delete a shared file')
            [CompletionResult]::new('download', 'download', [CompletionResultType]::ParameterValue, 'Download files')
            [CompletionResult]::new('exists', 'exists', [CompletionResultType]::ParameterValue, 'Check whether a remote file exists')
            [CompletionResult]::new('generate', 'generate', [CompletionResultType]::ParameterValue, 'Generate assets')
            [CompletionResult]::new('info', 'info', [CompletionResultType]::ParameterValue, 'Fetch info about a shared file')
            [CompletionResult]::new('parameters', 'parameters', [CompletionResultType]::ParameterValue, 'Change parameters of a shared file')
            [CompletionResult]::new('password', 'password', [CompletionResultType]::ParameterValue, 'Change the password of a shared file')
            [CompletionResult]::new('upload', 'upload', [CompletionResultType]::ParameterValue, 'Upload files')
            [CompletionResult]::new('version', 'version', [CompletionResultType]::ParameterValue, 'Determine the Send server version')
            [CompletionResult]::new('history', 'history', [CompletionResultType]::ParameterValue, 'View file history')
            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Prints this message or the help of the given subcommand(s)')
            break
        }
        'ffsend;debug' {
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'The remote host to upload to')
            [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'The remote host to upload to')
            [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('--timeout', 'timeout', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('--transfer-timeout', 'transfer-timeout', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--api', 'api', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--basic-auth', 'basic-auth', [CompletionResultType]::ParameterName, 'Protected proxy HTTP basic authentication credentials (not FxA)')
            [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('--history', 'history', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('--force', 'force', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('-I', 'I', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('--no-interact', 'no-interact', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('-y', 'y', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('-q', 'q', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('--quiet', 'quiet', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            [CompletionResult]::new('--incognito', 'incognito', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            break
        }
        'ffsend;delete' {
            [CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'Specify the file owner token')
            [CompletionResult]::new('--owner', 'owner', [CompletionResultType]::ParameterName, 'Specify the file owner token')
            [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('--timeout', 'timeout', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('--transfer-timeout', 'transfer-timeout', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--api', 'api', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--basic-auth', 'basic-auth', [CompletionResultType]::ParameterName, 'Protected proxy HTTP basic authentication credentials (not FxA)')
            [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('--history', 'history', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('--force', 'force', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('-I', 'I', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('--no-interact', 'no-interact', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('-y', 'y', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('-q', 'q', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('--quiet', 'quiet', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            [CompletionResult]::new('--incognito', 'incognito', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            break
        }
        'ffsend;download' {
            [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Unlock a password protected file')
            [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Unlock a password protected file')
            [CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'Output file or directory')
            [CompletionResult]::new('--output', 'output', [CompletionResultType]::ParameterName, 'Output file or directory')
            [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('--timeout', 'timeout', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('--transfer-timeout', 'transfer-timeout', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--api', 'api', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--basic-auth', 'basic-auth', [CompletionResultType]::ParameterName, 'Protected proxy HTTP basic authentication credentials (not FxA)')
            [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('--history', 'history', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'Extract an archived file')
            [CompletionResult]::new('--extract', 'extract', [CompletionResultType]::ParameterName, 'Extract an archived file')
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('--force', 'force', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('-I', 'I', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('--no-interact', 'no-interact', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('-y', 'y', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('-q', 'q', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('--quiet', 'quiet', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            [CompletionResult]::new('--incognito', 'incognito', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            break
        }
        'ffsend;exists' {
            [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('--timeout', 'timeout', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('--transfer-timeout', 'transfer-timeout', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--api', 'api', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--basic-auth', 'basic-auth', [CompletionResultType]::ParameterName, 'Protected proxy HTTP basic authentication credentials (not FxA)')
            [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('--history', 'history', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('--force', 'force', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('-I', 'I', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('--no-interact', 'no-interact', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('-y', 'y', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('-q', 'q', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('--quiet', 'quiet', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            [CompletionResult]::new('--incognito', 'incognito', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            break
        }
        'ffsend;generate' {
            [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('--timeout', 'timeout', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('--transfer-timeout', 'transfer-timeout', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--api', 'api', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--basic-auth', 'basic-auth', [CompletionResultType]::ParameterName, 'Protected proxy HTTP basic authentication credentials (not FxA)')
            [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('--history', 'history', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information')
            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('--force', 'force', [CompletionResultType]::ParameterName, 'Force the action, ignore warnings')
            [CompletionResult]::new('-I', 'I', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('--no-interact', 'no-interact', [CompletionResultType]::ParameterName, 'Not interactive, do not prompt')
            [CompletionResult]::new('-y', 'y', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Assume yes for prompts')
            [CompletionResult]::new('-q', 'q', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('--quiet', 'quiet', [CompletionResultType]::ParameterName, 'Produce output suitable for logging and automation')
            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Enable verbose information and logging')
            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            [CompletionResult]::new('--incognito', 'incognito', [CompletionResultType]::ParameterName, 'Don''t update local history for actions')
            [CompletionResult]::new('completions', 'completions', [CompletionResultType]::ParameterValue, 'Shell completions')
            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Prints this message or the help of the given subcommand(s)')
            break
        }
        'ffsend;generate;completions' {
            [CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'Shell completion files output directory')
            [CompletionResult]::new('--output', 'output', [CompletionResultType]::ParameterName, 'Shell completion files output directory')
            [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('--timeout', 'timeout', [CompletionResultType]::ParameterName, 'Request timeout (0 to disable)')
            [CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('--transfer-timeout', 'transfer-timeout', [CompletionResultType]::ParameterName, 'Transfer timeout (0 to disable)')
            [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--api', 'api', [CompletionResultType]::ParameterName, 'Server API version to use, ''-'' to lookup')
            [CompletionResult]::new('--basic-auth', 'basic-auth', [CompletionResultType]::ParameterName, 'Protected proxy HTTP basic authentication credentials (not FxA)')
            [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('--history', 'history', [CompletionResultType]::ParameterName, 'Use the specified history file')
            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information')
            [CompletionResult]::new('--help', 'help', [
Download .txt
gitextract_5263lj6x/

├── .gitattributes
├── .github/
│   └── FUNDING.yml
├── .gitignore
├── .gitlab-ci.yml
├── .travis.yml
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE
├── README.md
├── SECURITY.md
├── appveyor.yml
├── build.rs
├── contrib/
│   ├── completions/
│   │   ├── _ffsend
│   │   ├── _ffsend.ps1
│   │   ├── ffsend.bash
│   │   ├── ffsend.elv
│   │   ├── ffsend.fish
│   │   └── gen_completions
│   └── util/
│       └── nautilus/
│           ├── README.md
│           └── firefox-send
├── pkg/
│   ├── alpine/
│   │   └── APKBUILD
│   ├── aur/
│   │   ├── aur.pub
│   │   ├── ffsend/
│   │   │   └── PKGBUILD
│   │   ├── ffsend-bin/
│   │   │   └── PKGBUILD
│   │   └── ffsend-git/
│   │       └── PKGBUILD
│   ├── choco/
│   │   └── ffsend/
│   │       ├── ffsend.nuspec
│   │       └── tools/
│   │           ├── LICENSE.txt
│   │           └── VERIFICATION.txt
│   ├── create_deb
│   ├── deb/
│   │   ├── postinst
│   │   └── prerm
│   ├── docker/
│   │   └── Dockerfile
│   └── scoop/
│       ├── README.md
│       └── ffsend.json
├── res/
│   ├── asciinema-demo.json
│   └── asciinema-to-svg
└── src/
    ├── action/
    │   ├── debug.rs
    │   ├── delete.rs
    │   ├── download.rs
    │   ├── exists.rs
    │   ├── generate/
    │   │   ├── completions.rs
    │   │   └── mod.rs
    │   ├── history.rs
    │   ├── info.rs
    │   ├── mod.rs
    │   ├── params.rs
    │   ├── password.rs
    │   ├── upload.rs
    │   └── version.rs
    ├── archive/
    │   ├── archive.rs
    │   ├── archiver.rs
    │   └── mod.rs
    ├── client.rs
    ├── cmd/
    │   ├── arg/
    │   │   ├── api.rs
    │   │   ├── basic_auth.rs
    │   │   ├── download_limit.rs
    │   │   ├── expiry_time.rs
    │   │   ├── gen_passphrase.rs
    │   │   ├── host.rs
    │   │   ├── mod.rs
    │   │   ├── owner.rs
    │   │   ├── password.rs
    │   │   └── url.rs
    │   ├── handler.rs
    │   ├── matcher/
    │   │   ├── debug.rs
    │   │   ├── delete.rs
    │   │   ├── download.rs
    │   │   ├── exists.rs
    │   │   ├── generate/
    │   │   │   ├── completions.rs
    │   │   │   └── mod.rs
    │   │   ├── history.rs
    │   │   ├── info.rs
    │   │   ├── main.rs
    │   │   ├── mod.rs
    │   │   ├── params.rs
    │   │   ├── password.rs
    │   │   ├── upload.rs
    │   │   └── version.rs
    │   ├── mod.rs
    │   └── subcmd/
    │       ├── debug.rs
    │       ├── delete.rs
    │       ├── download.rs
    │       ├── exists.rs
    │       ├── generate/
    │       │   ├── completions.rs
    │       │   └── mod.rs
    │       ├── history.rs
    │       ├── info.rs
    │       ├── mod.rs
    │       ├── params.rs
    │       ├── password.rs
    │       ├── upload.rs
    │       └── version.rs
    ├── config.rs
    ├── error.rs
    ├── history.rs
    ├── history_tool.rs
    ├── host.rs
    ├── main.rs
    ├── progress.rs
    ├── urlshorten.rs
    └── util.rs
Download .txt
SYMBOL INDEX (379 symbols across 63 files)

FILE: build.rs
  function main (line 1) | fn main() {

FILE: src/action/debug.rs
  type Debug (line 14) | pub struct Debug<'a> {
  function new (line 20) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 26) | pub fn invoke(&self) -> Result<(), ActionError> {

FILE: src/action/delete.rs
  type Delete (line 13) | pub struct Delete<'a> {
  function new (line 19) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 25) | pub fn invoke(&self) -> Result<(), ActionError> {
  type Error (line 66) | pub enum Error {
    method from (line 82) | fn from(err: FileParseError) -> Error {
    method from (line 88) | fn from(err: DeleteError) -> Error {

FILE: src/action/download.rs
  type Download (line 33) | pub struct Download<'a> {
  function new (line 39) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 45) | pub fn invoke(&self) -> Result<(), Error> {
  function prepare_path (line 217) | fn prepare_path(
  function select_path (line 288) | fn select_path(target: &PathBuf, name_hint: &str) -> PathBuf {
  type Error (line 353) | pub enum Error {
    method from (line 387) | fn from(err: VersionError) -> Error {
    method from (line 393) | fn from(err: FileParseError) -> Error {
    method from (line 399) | fn from(err: ExistsError) -> Error {
    method from (line 405) | fn from(err: MetadataError) -> Error {
    method from (line 411) | fn from(err: DownloadError) -> Error {
    method from (line 418) | fn from(err: ExtractError) -> Error {
  type ExtractError (line 425) | pub enum ExtractError {

FILE: src/action/exists.rs
  type Exists (line 13) | pub struct Exists<'a> {
  function new (line 19) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 25) | pub fn invoke(&self) -> Result<(), ActionError> {
  type Error (line 65) | pub enum Error {
    method from (line 77) | fn from(err: FileParseError) -> Error {
    method from (line 83) | fn from(err: ExistsError) -> Error {

FILE: src/action/generate/completions.rs
  type Completions (line 10) | pub struct Completions<'a> {
  function new (line 16) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 22) | pub fn invoke(&self) -> Result<(), ActionError> {
  type Error (line 57) | pub enum Error {

FILE: src/action/generate/mod.rs
  type Generate (line 10) | pub struct Generate<'a> {
  function new (line 16) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 22) | pub fn invoke(&self) -> Result<(), ActionError> {

FILE: src/action/history.rs
  type History (line 11) | pub struct History<'a> {
  function new (line 17) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 23) | pub fn invoke(&self) -> Result<(), ActionError> {
  type Error (line 146) | pub enum Error {
  method from (line 153) | fn from(err: HistoryLoadError) -> ActionError {

FILE: src/action/info.rs
  type Info (line 19) | pub struct Info<'a> {
  function new (line 25) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 31) | pub fn invoke(&self) -> Result<(), Error> {
  type Error (line 164) | pub enum Error {
    method from (line 184) | fn from(err: FileParseError) -> Error {
    method from (line 190) | fn from(err: ExistsError) -> Error {
    method from (line 196) | fn from(err: InfoError) -> Error {

FILE: src/action/mod.rs
  function select_api_version (line 27) | fn select_api_version(

FILE: src/action/params.rs
  type Params (line 14) | pub struct Params<'a> {
  function new (line 20) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 26) | pub fn invoke(&self) -> Result<(), ActionError> {

FILE: src/action/password.rs
  type Password (line 14) | pub struct Password<'a> {
  function new (line 20) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 26) | pub fn invoke(&self) -> Result<(), ActionError> {

FILE: src/action/upload.rs
  type Upload (line 42) | pub struct Upload<'a> {
  function new (line 48) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 54) | pub fn invoke(&self) -> Result<(), Error> {
  function shared_dir (line 553) | fn shared_dir(paths: Vec<PathBuf>) -> Option<PathBuf> {
  type Error (line 604) | pub enum Error {
    method from (line 633) | fn from(err: VersionError) -> Error {
    method from (line 640) | fn from(err: ArchiveError) -> Error {
    method from (line 646) | fn from(err: UploadError) -> Error {
  type ArchiveError (line 653) | pub enum ArchiveError {

FILE: src/action/version.rs
  type Version (line 10) | pub struct Version<'a> {
  function new (line 16) | pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
  function invoke (line 22) | pub fn invoke(&self) -> Result<(), ActionError> {
  type Error (line 50) | pub enum Error {
    method from (line 57) | fn from(err: VersionError) -> Error {

FILE: src/archive/archive.rs
  type Result (line 6) | pub type Result<T> = ::std::result::Result<T, IoError>;
  type Archive (line 8) | pub struct Archive<R: Read> {
  function new (line 15) | pub fn new(reader: R) -> Archive<R> {
  function extract (line 22) | pub fn extract<P: AsRef<Path>>(&mut self, destination: P) -> Result<()> {

FILE: src/archive/archiver.rs
  type Result (line 7) | pub type Result<T> = ::std::result::Result<T, IoError>;
  type Archiver (line 9) | pub struct Archiver<W: Write> {
  function new (line 16) | pub fn new(writer: W) -> Archiver<W> {
  function append_path (line 28) | pub fn append_path<P, Q>(&mut self, path: P, src_path: Q) -> Result<()>
  function append_file (line 45) | pub fn append_file<P>(&mut self, path: P, file: &mut File) -> Result<()>
  function append_dir (line 54) | pub fn append_dir<P, Q>(&mut self, path: P, src_path: Q) -> Result<()>
  function finish (line 63) | pub fn finish(mut self) -> Result<()> {

FILE: src/client.rs
  function create_config (line 12) | pub fn create_config(matcher_main: &MainMatcher) -> ClientConfig {
  function to_duration (line 23) | pub fn to_duration(secs: u64) -> Option<Duration> {

FILE: src/cmd/arg/api.rs
  type ArgApi (line 9) | pub struct ArgApi {}
    type Value (line 35) | type Value = DesiredVersion;
    method value (line 37) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value {
  method name (line 12) | fn name() -> &'static str {
  method build (line 16) | fn build<'b, 'c>() -> Arg<'b, 'c> {
  function is_auto (line 62) | fn is_auto(arg: &str) -> bool {

FILE: src/cmd/arg/basic_auth.rs
  type ArgBasicAuth (line 6) | pub struct ArgBasicAuth {}
    type Value (line 28) | type Value = Option<(String, Option<String>)>;
    method value (line 30) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value {
  method name (line 9) | fn name() -> &'static str {
  method build (line 13) | fn build<'b, 'c>() -> Arg<'b, 'c> {

FILE: src/cmd/arg/download_limit.rs
  type ArgDownloadLimit (line 10) | pub struct ArgDownloadLimit {}
    method value_checked (line 13) | pub fn value_checked<'a>(
    type Value (line 79) | type Value = Option<usize>;
    method value (line 81) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value {
  method name (line 60) | fn name() -> &'static str {
  method build (line 64) | fn build<'b, 'c>() -> Arg<'b, 'c> {
  function closest (line 88) | fn closest(values: &[usize], current: usize) -> usize {

FILE: src/cmd/arg/expiry_time.rs
  type ArgExpiryTime (line 14) | pub struct ArgExpiryTime {}
    method value_checked (line 17) | pub fn value_checked<'a>(
    type Value (line 86) | type Value = Option<usize>;
    method value (line 88) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value {
  method name (line 67) | fn name() -> &'static str {
  method build (line 71) | fn build<'b, 'c>() -> Arg<'b, 'c> {

FILE: src/cmd/arg/gen_passphrase.rs
  type ArgGenPassphrase (line 7) | pub struct ArgGenPassphrase {}
    method gen_passphrase (line 12) | pub fn gen_passphrase() -> String {
  method name (line 18) | fn name() -> &'static str {
  method build (line 22) | fn build<'b, 'c>() -> Arg<'b, 'c> {

FILE: src/cmd/arg/host.rs
  type ArgHost (line 10) | pub struct ArgHost {}
    type Value (line 30) | type Value = Url;
    method value (line 32) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value {
  method name (line 13) | fn name() -> &'static str {
  method build (line 17) | fn build<'b, 'c>() -> Arg<'b, 'c> {

FILE: src/cmd/arg/mod.rs
  type CmdArg (line 27) | pub trait CmdArg {
    method name (line 29) | fn name() -> &'static str;
    method build (line 32) | fn build<'a, 'b>() -> Arg<'a, 'b>;
  type CmdArgFlag (line 38) | pub trait CmdArgFlag: CmdArg {
    method is_present (line 40) | fn is_present<'a>(matches: &ArgMatches<'a>) -> bool {
  type CmdArgOption (line 47) | pub trait CmdArgOption<'a>: CmdArg {
    method value (line 52) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value;
    method value_raw (line 55) | fn value_raw<'b: 'a>(matches: &'a ArgMatches<'b>) -> Option<&'a str> {

FILE: src/cmd/arg/owner.rs
  type ArgOwner (line 8) | pub struct ArgOwner {}
    type Value (line 30) | type Value = Option<String>;
    method value (line 32) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value {
  method name (line 11) | fn name() -> &'static str {
  method build (line 15) | fn build<'b, 'c>() -> Arg<'b, 'c> {

FILE: src/cmd/arg/password.rs
  type ArgPassword (line 8) | pub struct ArgPassword {}
    type Value (line 29) | type Value = Option<String>;
    method value (line 31) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value {
  method name (line 11) | fn name() -> &'static str {
  method build (line 15) | fn build<'b, 'c>() -> Arg<'b, 'c> {

FILE: src/cmd/arg/url.rs
  type ArgUrl (line 10) | pub struct ArgUrl {}
    type Value (line 26) | type Value = Url;
    method value (line 28) | fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value {
  method name (line 13) | fn name() -> &'static str {
  method build (line 17) | fn build<'b, 'c>() -> Arg<'b, 'c> {

FILE: src/cmd/handler.rs
  type Handler (line 52) | pub struct Handler<'a> {
  function build (line 59) | pub fn build() -> App<'a, 'b> {
  function parse (line 202) | pub fn parse() -> Handler<'a> {
  function infer_subcommand (line 227) | fn infer_subcommand(args: &mut Vec<OsString>) {
  function matches (line 241) | pub fn matches(&'a self) -> &'a ArgMatches {
  function debug (line 246) | pub fn debug(&'a self) -> Option<DebugMatcher> {
  function delete (line 251) | pub fn delete(&'a self) -> Option<DeleteMatcher> {
  function download (line 256) | pub fn download(&'a self) -> Option<DownloadMatcher> {
  function exists (line 261) | pub fn exists(&'a self) -> Option<ExistsMatcher> {
  function generate (line 266) | pub fn generate(&'a self) -> Option<GenerateMatcher> {
  function history (line 272) | pub fn history(&'a self) -> Option<HistoryMatcher> {
  function info (line 277) | pub fn info(&'a self) -> Option<InfoMatcher> {
  function params (line 282) | pub fn params(&'a self) -> Option<ParamsMatcher> {
  function password (line 287) | pub fn password(&'a self) -> Option<PasswordMatcher> {
  function upload (line 292) | pub fn upload(&'a self) -> Option<UploadMatcher> {
  function version (line 297) | pub fn version(&'a self) -> Option<VersionMatcher> {

FILE: src/cmd/matcher/debug.rs
  type DebugMatcher (line 8) | pub struct DebugMatcher<'a> {
  function host (line 18) | pub fn host(&'a self) -> Url {
  function with (line 24) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/delete.rs
  type DeleteMatcher (line 8) | pub struct DeleteMatcher<'a> {
  function url (line 18) | pub fn url(&'a self) -> Url {
  function owner (line 23) | pub fn owner(&'a self) -> Option<String> {
  function with (line 30) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/download.rs
  type DownloadMatcher (line 12) | pub struct DownloadMatcher<'a> {
  function url (line 22) | pub fn url(&'a self) -> Url {
  function guess_host (line 29) | pub fn guess_host(&'a self, url: Option<Url>) -> Url {
  function password (line 39) | pub fn password(&'a self) -> Option<String> {
  function output (line 46) | pub fn output(&'a self) -> PathBuf {
  function extract (line 55) | pub fn extract(&self) -> bool {
  function with (line 61) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/exists.rs
  type ExistsMatcher (line 9) | pub struct ExistsMatcher<'a> {
  function url (line 19) | pub fn url(&'a self) -> Url {
  function with (line 25) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/generate/completions.rs
  type CompletionsMatcher (line 9) | pub struct CompletionsMatcher<'a> {
  function shells (line 15) | pub fn shells(&'a self) -> Vec<Shell> {
  function output (line 49) | pub fn output(&'a self) -> PathBuf {
  function with (line 58) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/generate/mod.rs
  type GenerateMatcher (line 9) | pub struct GenerateMatcher<'a> {
  function matcher_completions (line 16) | pub fn matcher_completions(&'a self) -> Option<CompletionsMatcher> {
  function with (line 22) | fn with(root: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/history.rs
  type HistoryMatcher (line 10) | pub struct HistoryMatcher<'a> {
  function clear (line 17) | pub fn clear(&self) -> bool {
  function rm (line 26) | pub fn rm(&'a self) -> Option<Url> {
  function with (line 42) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/info.rs
  type InfoMatcher (line 9) | pub struct InfoMatcher<'a> {
  function url (line 19) | pub fn url(&'a self) -> Url {
  function owner (line 24) | pub fn owner(&'a self) -> Option<String> {
  function password (line 31) | pub fn password(&'a self) -> Option<String> {
  function with (line 37) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/main.rs
  type MainMatcher (line 14) | pub struct MainMatcher<'a> {
  function force (line 20) | pub fn force(&self) -> bool {
  function no_interact (line 25) | pub fn no_interact(&self) -> bool {
  function assume_yes (line 30) | pub fn assume_yes(&self) -> bool {
  function api (line 35) | pub fn api(&'a self) -> DesiredVersion {
  function basic_auth (line 40) | pub fn basic_auth(&'a self) -> Option<(String, Option<String>)> {
  function history (line 46) | pub fn history(&self) -> PathBuf {
  function timeout (line 65) | pub fn timeout(&self) -> u64 {
  function transfer_timeout (line 73) | pub fn transfer_timeout(&self) -> u64 {
  function incognito (line 82) | pub fn incognito(&self) -> bool {
  function quiet (line 87) | pub fn quiet(&self) -> bool {
  function verbose (line 92) | pub fn verbose(&self) -> bool {
  function with (line 98) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/mod.rs
  type Matcher (line 32) | pub trait Matcher<'a>: Sized {
    method with (line 34) | fn with(matches: &'a ArgMatches) -> Option<Self>;

FILE: src/cmd/matcher/params.rs
  type ParamsMatcher (line 12) | pub struct ParamsMatcher<'a> {
  function url (line 22) | pub fn url(&'a self) -> Url {
  function owner (line 27) | pub fn owner(&'a self) -> Option<String> {
  function download_limit (line 36) | pub fn download_limit(
  function with (line 47) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/password.rs
  type PasswordMatcher (line 10) | pub struct PasswordMatcher<'a> {
  function url (line 20) | pub fn url(&'a self) -> Url {
  function owner (line 25) | pub fn owner(&'a self) -> Option<String> {
  function password (line 34) | pub fn password(&'a self) -> (String, bool) {
  function with (line 63) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/matcher/upload.rs
  type UploadMatcher (line 15) | pub struct UploadMatcher<'a> {
  function files (line 22) | pub fn files(&'a self) -> Vec<&'a str> {
  function name (line 33) | pub fn name(&'a self) -> Option<&'a str> {
  function host (line 58) | pub fn host(&'a self) -> Url {
  function password (line 69) | pub fn password(&'a self) -> Option<(String, bool)> {
  function download_limit (line 83) | pub fn download_limit(
  function expiry_time (line 100) | pub fn expiry_time(
  function archive (line 111) | pub fn archive(&self) -> bool {
  function open (line 116) | pub fn open(&self) -> bool {
  function delete (line 121) | pub fn delete(&self) -> bool {
  function copy (line 127) | pub fn copy(&self) -> Option<CopyMode> {
  function shorten (line 144) | pub fn shorten(&self) -> bool {
  function qrcode (line 150) | pub fn qrcode(&self) -> bool {
  function with (line 156) | fn with(matches: &'a ArgMatches) -> Option<Self> {
  type CopyMode (line 165) | pub enum CopyMode {
    method build (line 175) | pub fn build(&self, url: &str) -> String {

FILE: src/cmd/matcher/version.rs
  type VersionMatcher (line 9) | pub struct VersionMatcher<'a> {
  function host (line 19) | pub fn host(&'a self) -> Url {
  function with (line 25) | fn with(matches: &'a ArgMatches) -> Option<Self> {

FILE: src/cmd/subcmd/debug.rs
  type CmdDebug (line 6) | pub struct CmdDebug;
    method build (line 9) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/delete.rs
  type CmdDelete (line 6) | pub struct CmdDelete;
    method build (line 9) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/download.rs
  type CmdDownload (line 6) | pub struct CmdDownload;
    method build (line 9) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/exists.rs
  type CmdExists (line 6) | pub struct CmdExists;
    method build (line 9) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/generate/completions.rs
  type CmdCompletions (line 4) | pub struct CmdCompletions;
    method build (line 7) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/generate/mod.rs
  type CmdGenerate (line 8) | pub struct CmdGenerate;
    method build (line 11) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/history.rs
  type CmdHistory (line 4) | pub struct CmdHistory;
    method build (line 7) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/info.rs
  type CmdInfo (line 6) | pub struct CmdInfo;
    method build (line 9) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/params.rs
  type CmdParams (line 6) | pub struct CmdParams;
    method build (line 9) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/password.rs
  type CmdPassword (line 6) | pub struct CmdPassword;
    method build (line 9) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/upload.rs
  type CmdUpload (line 8) | pub struct CmdUpload;
    method build (line 11) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/cmd/subcmd/version.rs
  type CmdVersion (line 6) | pub struct CmdVersion;
    method build (line 9) | pub fn build<'a, 'b>() -> App<'a, 'b> {

FILE: src/config.rs
  constant CLIENT_TIMEOUT (line 7) | pub const CLIENT_TIMEOUT: u64 = 30;
  constant CLIENT_TRANSFER_TIMEOUT (line 11) | pub const CLIENT_TRANSFER_TIMEOUT: u64 = 24 * 60 * 60;
  constant API_VERSION_DESIRED_DEFAULT (line 14) | pub const API_VERSION_DESIRED_DEFAULT: DesiredVersion = DesiredVersion::...
  constant API_VERSION_ASSUME (line 18) | pub const API_VERSION_ASSUME: Version = Version::V3;
  constant API_VERSION_ASSUME (line 20) | pub const API_VERSION_ASSUME: Version = Version::V2;

FILE: src/error.rs
  type Error (line 16) | pub enum Error {
    method from (line 23) | fn from(err: CliDownloadError) -> Error {
    method from (line 29) | fn from(err: CliInfoError) -> Error {
    method from (line 35) | fn from(err: CliUploadError) -> Error {
    method from (line 41) | fn from(err: ActionError) -> Error {
  type ActionError (line 47) | pub enum ActionError {
    method from (line 96) | fn from(err: DeleteError) -> ActionError {
    method from (line 102) | fn from(err: ExistsError) -> ActionError {
    method from (line 108) | fn from(err: CliGenerateCompletionsError) -> ActionError {
    method from (line 115) | fn from(err: CliHistoryError) -> ActionError {
    method from (line 121) | fn from(err: ParamsError) -> ActionError {
    method from (line 127) | fn from(err: PasswordError) -> ActionError {
    method from (line 133) | fn from(err: VersionError) -> ActionError {
    method from (line 139) | fn from(err: FileParseError) -> ActionError {

FILE: src/history.rs
  constant VERSION_MIN (line 16) | const VERSION_MIN: &str = "0.0.1";
  constant VERSION_MAX (line 19) | const VERSION_MAX: &str = crate_version!();
  type History (line 22) | pub struct History {
    method new (line 42) | pub fn new(autosave: Option<PathBuf>) -> Self {
    method load (line 49) | pub fn load(path: PathBuf) -> Result<Self, LoadError> {
    method load_or_new (line 82) | pub fn load_or_new(file: PathBuf) -> Result<Self, LoadError> {
    method save (line 91) | pub fn save(&mut self) -> Result<(), SaveError> {
    method add (line 142) | pub fn add(&mut self, file: RemoteFile, overwrite: bool) {
    method remove (line 172) | pub fn remove(&mut self, id: &str) -> bool {
    method remove_url (line 197) | pub fn remove_url(&mut self, url: Url) -> Result<bool, FileParseError> {
    method files (line 202) | pub fn files(&self) -> &Vec<RemoteFile> {
    method get_file (line 210) | pub fn get_file(&self, file: &RemoteFile) -> Option<&RemoteFile> {
    method clear (line 217) | pub fn clear(&mut self) {
    method gc (line 228) | pub fn gc(&mut self) -> usize {
  method drop (line 253) | fn drop(&mut self) {
  method default (line 265) | fn default() -> Self {
  type Error (line 276) | pub enum Error {
    method from (line 287) | fn from(err: LoadError) -> Self {
    method from (line 293) | fn from(err: SaveError) -> Self {
  type LoadError (line 299) | pub enum LoadError {
    method from (line 310) | fn from(err: IoError) -> Self {
    method from (line 316) | fn from(err: DeError) -> Self {
  type SaveError (line 322) | pub enum SaveError {
    method from (line 346) | fn from(err: SerError) -> Self {
    method from (line 352) | fn from(err: IoError) -> Self {

FILE: src/history_tool.rs
  function add_error (line 16) | fn add_error(
  function add (line 41) | pub fn add(matcher_main: &MainMatcher, file: RemoteFile, overwrite: bool) {
  function remove_error (line 50) | fn remove_error(matcher_main: &MainMatcher, file: &RemoteFile) -> Result...
  function remove (line 66) | pub fn remove(matcher_main: &MainMatcher, file: &RemoteFile) -> bool {
  function derive_file_properties (line 90) | pub fn derive_file_properties(matcher_main: &MainMatcher, file: &mut Rem...

FILE: src/host.rs
  function parse_host (line 4) | pub fn parse_host(host: &str) -> Result<Url, HostError> {
  type HostError (line 27) | pub enum HostError {

FILE: src/main.rs
  function main (line 52) | fn main() {
  function invoke_action (line 69) | fn invoke_action(handler: &Handler) -> Result<(), Error> {
  function print_main_info (line 161) | pub fn print_main_info() -> ! {

FILE: src/progress.rs
  constant PROGRESS_BAR_FPS_MILLIS (line 8) | const PROGRESS_BAR_FPS_MILLIS: u64 = 200;
  type ProgressBar (line 11) | pub struct ProgressBar<'a> {
  function new (line 19) | pub fn new(msg_progress: &'a str, msg_finish: &'a str) -> ProgressBar<'a> {
  function new_upload (line 28) | pub fn new_upload() -> ProgressBar<'a> {
  function new_download (line 33) | pub fn new_download() -> ProgressBar<'a> {
  method start (line 40) | fn start(&mut self, total: u64) {
  method progress (line 51) | fn progress(&mut self, progress: u64) {
  method finish (line 59) | fn finish(&mut self) {

FILE: src/urlshorten.rs
  type Result (line 15) | type Result<T> = ::std::result::Result<T, Error>;
  function shorten (line 18) | pub fn shorten(client: &Client, url: &str) -> Result<String> {
  function shorten_url (line 24) | pub fn shorten_url(client: &Client, url: &Url) -> Result<Url> {
  function request (line 29) | fn request(client: &Client, req: Request) -> Result<String> {
  type Error (line 70) | pub enum Error {
    method from (line 89) | fn from(err: url::ParseError) -> Self {
    method from (line 95) | fn from(err: ResponseError) -> Self {

FILE: src/util.rs
  function print_success (line 49) | pub fn print_success(msg: &str) {
  function print_error (line 55) | pub fn print_error<E: Fail>(err: impl Borrow<E>) {
  function print_error_msg (line 84) | pub fn print_error_msg<S>(err: S)
  function print_warning (line 92) | pub fn print_warning<S>(err: S)
  function quit (line 100) | pub fn quit() -> ! {
  function quit_error (line 106) | pub fn quit_error<E: Fail>(err: E, hints: impl Borrow<ErrorHints>) -> ! {
  function quit_error_msg (line 119) | pub fn quit_error_msg<S>(err: S, hints: impl Borrow<ErrorHints>) -> !
  type ErrorHints (line 129) | pub struct ErrorHints {
    method any (line 161) | pub fn any(&self) -> bool {
    method print (line 177) | pub fn print(&self) {
  method default (line 240) | fn default() -> Self {
  method add_info (line 258) | pub fn add_info(mut self, info: String) -> Self {
  function highlight (line 274) | pub fn highlight(msg: &str) -> ColoredString {
  function highlight_error (line 279) | pub fn highlight_error(msg: &str) -> ColoredString {
  function highlight_warning (line 284) | pub fn highlight_warning(msg: &str) -> ColoredString {
  function highlight_info (line 289) | pub fn highlight_info(msg: &str) -> ColoredString {
  function open_url (line 295) | pub fn open_url(url: impl Borrow<Url>) -> Result<(), IoError> {
  function open_path (line 301) | pub fn open_path(path: &str) -> Result<(), IoError> {
  function set_clipboard (line 307) | pub fn set_clipboard(content: String) -> Result<(), ClipboardError> {
  type ClipboardType (line 325) | pub enum ClipboardType {
    method select (line 346) | pub fn select() -> Self {
    method set (line 370) | pub fn set(&self, content: String) -> Result<(), ClipboardError> {
    method native_set (line 385) | fn native_set(content: String) -> Result<(), ClipboardError> {
    method xclip_set (line 393) | fn xclip_set(path: Option<String>, content: &str) -> Result<(), Clipbo...
    method xsel_set (line 404) | fn xsel_set(path: Option<String>, content: &str) -> Result<(), Clipboa...
    method sys_cmd_set (line 413) | fn sys_cmd_set(
    method fmt (line 454) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  type ClipboardError (line 474) | pub enum ClipboardError {
  function check_empty_password (line 507) | pub fn check_empty_password(password: &str, matcher_main: &MainMatcher) {
  function prompt_password (line 523) | pub fn prompt_password(main_matcher: &MainMatcher, optional: bool) -> Op...
  function ensure_password (line 576) | pub fn ensure_password(
  function prompt (line 626) | pub fn prompt(msg: &str, main_matcher: &MainMatcher) -> String {
  function prompt_yes (line 660) | pub fn prompt_yes(msg: &str, def: Option<bool>, main_matcher: &MainMatch...
  function derive_bool (line 713) | fn derive_bool(input: &str) -> Option<bool> {
  function prompt_owner_token (line 737) | pub fn prompt_owner_token(main_matcher: &MainMatcher, optional: bool) ->...
  function ensure_owner_token (line 759) | pub fn ensure_owner_token(
  function format_bytes (line 816) | pub fn format_bytes(bytes: u64) -> String {
  function parse_duration (line 842) | pub fn parse_duration(duration: &str) -> Result<usize, ParseDurationErro...
  type ParseDurationError (line 877) | pub enum ParseDurationError {
  function format_duration (line 911) | pub fn format_duration(duration: impl Borrow<Duration>) -> String {
  function format_bool (line 942) | pub fn format_bool(b: bool) -> &'static str {
  function bin_name (line 958) | pub fn bin_name() -> String {
  function ensure_enough_space (line 977) | pub fn ensure_enough_space<P: AsRef<Path>>(path: P, size: u64) {
  function app_project_dirs (line 1016) | pub fn app_project_dirs() -> ProjectDirs {
  function app_history_file_path (line 1023) | pub fn app_history_file_path() -> PathBuf {
  function app_history_file_path_string (line 1029) | pub fn app_history_file_path_string() -> String {
  function env_var_present (line 1036) | pub fn env_var_present(key: impl AsRef<OsStr>) -> bool {
  function features_list (line 1041) | pub fn features_list() -> Vec<&'static str> {
  function api_version_list (line 1078) | pub fn api_version_list() -> Vec<&'static str> {
  function follow_url (line 1097) | pub fn follow_url(client: &Client, url: &Url) -> Result<Url, FollowError> {
  type FollowError (line 1111) | pub enum FollowError {
    method from (line 1122) | fn from(err: ResponseError) -> Self {
  function rand_alphanum_string (line 1128) | pub fn rand_alphanum_string(len: usize) -> String {
  function stdin_read_file (line 1137) | pub fn stdin_read_file(prompt: bool) -> Result<Vec<u8>, StdinErr> {
  type StdinErr (line 1155) | pub enum StdinErr {
Condensed preview — 101 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (683K chars).
[
  {
    "path": ".gitattributes",
    "chars": 146,
    "preview": "# Mark generated completion files as vendored\ncontrib/completions/* linguist-vendored\ncontrib/completions/gen_completion"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 113,
    "preview": "# Funding links\ngithub:\n  - timvisee\ncustom:\n  - \"https://timvisee.com/donate\"\npatreon: timvisee\nko_fi: timvisee\n"
  },
  {
    "path": ".gitignore",
    "chars": 52,
    "preview": ".*.sw[po]\ntarget/\n**/*.rs.bk\n.idea/\nsnapcraft.login\n"
  },
  {
    "path": ".gitlab-ci.yml",
    "chars": 14297,
    "preview": "# GitLab CI configuration for ffsend builds, tests and releases\n#\n# To add a new release:\n# - configure a new 'build-*' "
  },
  {
    "path": ".travis.yml",
    "chars": 1857,
    "preview": "# Travis CI configuration for building macOS binaries for ffsend.\n# These macOS binaries are published on GitHub as rele"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 5606,
    "preview": "# Contributing\n\n**Repository:**\n- [GitLab repository][gitlab]\n- _Mirror: [GitHub repository][github]_\n\n**Issues:** (bug "
  },
  {
    "path": "Cargo.toml",
    "chars": 3872,
    "preview": "[package]\nname = \"ffsend\"\nversion = \"0.2.77\"\nrust-version = \"1.63.0\"\nauthors = [\"Tim Visee <3a4fb3964f@sinenomine.email>"
  },
  {
    "path": "LICENSE",
    "chars": 35149,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 31613,
    "preview": "[![Build status on GitLab CI][gitlab-ci-master-badge]][gitlab-ci-link]\n[![Newest release on crates.io][crate-version-bad"
  },
  {
    "path": "SECURITY.md",
    "chars": 745,
    "preview": "# Security Policy\n\n## Supported Versions\n\n| Version | Supported          |\n| ------- | ------------------ |\n| 0.2.x   | "
  },
  {
    "path": "appveyor.yml",
    "chars": 3446,
    "preview": "# AppVeyor CI configuration for building Windows binaries for ffsend.\n# These Windows binaries are published on GitHub a"
  },
  {
    "path": "build.rs",
    "chars": 1032,
    "preview": "fn main() {\n    #[cfg(all(\n        feature = \"clipboard\",\n        any(\n            target_os = \"linux\",\n            targ"
  },
  {
    "path": "contrib/completions/_ffsend",
    "chars": 75037,
    "preview": "#compdef ffsend\n\nautoload -U is-at-least\n\n_ffsend() {\n    typeset -A opt_args\n    typeset -a _arguments_options\n    loca"
  },
  {
    "path": "contrib/completions/_ffsend.ps1",
    "chars": 59693,
    "preview": "\nusing namespace System.Management.Automation\nusing namespace System.Management.Automation.Language\n\nRegister-ArgumentCo"
  },
  {
    "path": "contrib/completions/ffsend.bash",
    "chars": 88412,
    "preview": "_ffsend() {\n    local i cur prev opts cmds\n    COMPREPLY=()\n    cur=\"${COMP_WORDS[COMP_CWORD]}\"\n    prev=\"${COMP_WORDS[C"
  },
  {
    "path": "contrib/completions/ffsend.elv",
    "chars": 27809,
    "preview": "\nedit:completion:arg-completer[ffsend] = [@words]{\n    fn spaces [n]{\n        repeat $n ' ' | joins ''\n    }\n    fn cand"
  },
  {
    "path": "contrib/completions/ffsend.fish",
    "chars": 27209,
    "preview": "complete -c ffsend -n \"__fish_use_subcommand\" -s t -l timeout -d 'Request timeout (0 to disable)'\ncomplete -c ffsend -n "
  },
  {
    "path": "contrib/completions/gen_completions",
    "chars": 177,
    "preview": "#!/usr/bin/env bash\n\n# Stop on error\nset -e\n\necho \"Generating all completions using cargo debug binary...\"\ncargo run -q "
  },
  {
    "path": "contrib/util/nautilus/README.md",
    "chars": 422,
    "preview": "`firefox-send` is a script for Nautilus/Nemo/Caja (maybe it needs some adaptation for Caja) to send files directly from "
  },
  {
    "path": "contrib/util/nautilus/firefox-send",
    "chars": 1666,
    "preview": "#!/bin/bash\n\n\n#CONSTANTS\n#FILEPATH=`echo $NAUTILUS_SCRIPT_SELECTED_URIS | sed 's@file://@@g'`\n# Quote the paths\nIFS=$'\\n"
  },
  {
    "path": "pkg/alpine/APKBUILD",
    "chars": 1710,
    "preview": "# Contributor: Rasmus Thomsen <oss@cogitri.dev>\n# Maintainer: Rasmus Thomsen <oss@cogitri.dev>\npkgname=ffsend\npkgver=0.2"
  },
  {
    "path": "pkg/aur/aur.pub",
    "chars": 394,
    "preview": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHfiNi+rOCPKGLB6v9uuYR6GkN6Zd+CdaRbV82A26AUzs48ZG0xZGXHsoRuZY/yCUhcrS2u9xZ16fsAxny"
  },
  {
    "path": "pkg/aur/ffsend/PKGBUILD",
    "chars": 1716,
    "preview": "# Maintainer: Tim Visee <tim@visee.me>\n#\n# This PKGBUILD is managed externally, and is automatically updated here:\n# - h"
  },
  {
    "path": "pkg/aur/ffsend-bin/PKGBUILD",
    "chars": 1901,
    "preview": "# Maintainer: Tim Visee <tim@visee.me>\n# Contributor: Ariel AxionL <i at axionl dot me>\n#\n# This PKGBUILD is managed ext"
  },
  {
    "path": "pkg/aur/ffsend-git/PKGBUILD",
    "chars": 1627,
    "preview": "# Maintainer: Tim Visee <tim@visee.me>\n#\n# This PKGBUILD is managed externally, and is automatically updated here:\n# - h"
  },
  {
    "path": "pkg/choco/ffsend/ffsend.nuspec",
    "chars": 4579,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<!-- Read this before creating packages: https://chocolatey.org/docs/create-pac"
  },
  {
    "path": "pkg/choco/ffsend/tools/LICENSE.txt",
    "chars": 35873,
    "preview": "From: https://www.gnu.org/licenses/gpl-3.0.en.html\r\n\r\nLICENSE\r\n\r\n                    GNU GENERAL PUBLIC LICENSE\r\n      "
  },
  {
    "path": "pkg/choco/ffsend/tools/VERIFICATION.txt",
    "chars": 250,
    "preview": "VERIFICATION\r\nVerification is intended to assist the Chocolatey moderators and community\r\nin verifying that this packag"
  },
  {
    "path": "pkg/create_deb",
    "chars": 1624,
    "preview": "#!/usr/bin/env bash\n\nset -e\n\n# Ensure the version tag is valid\nif [[ ! $TRAVIS_TAG =~ ^v([0-9]+\\.)*[0-9]+$ ]]; then\n    "
  },
  {
    "path": "pkg/deb/postinst",
    "chars": 162,
    "preview": "#!/usr/bin/env bash\n\n# Create an ffs alias\nif [[ ! -f /usr/bin/ffs ]]; then\n    echo \"Creating ffs alias for ffsend...\"\n"
  },
  {
    "path": "pkg/deb/prerm",
    "chars": 231,
    "preview": "#!/usr/bin/env bash\n\n# Unlink the ffs alias if it links to ffsend\nif [[ -L /usr/bin/ffs ]] \\\n    && [[ $(realpath /usr/b"
  },
  {
    "path": "pkg/docker/Dockerfile",
    "chars": 134,
    "preview": "FROM alpine:latest\nLABEL maintainer=\"Tim Visée <3a4fb3964f@sinenomine.email>\"\n\nCOPY ./ffsend /\n\nWORKDIR /data/\nENTRYPOIN"
  },
  {
    "path": "pkg/scoop/README.md",
    "chars": 307,
    "preview": "# scoop manifest for ffsend\nThis directory contains a [`scoop`][scoop] manifest template for `ffsend`.\n\nThe currently pu"
  },
  {
    "path": "pkg/scoop/ffsend.json",
    "chars": 788,
    "preview": "{\n    \"homepage\": \"https://github.com/timvisee/ffsend\",\n    \"description\": \"Easily and securely share files from the com"
  },
  {
    "path": "res/asciinema-demo.json",
    "chars": 16200,
    "preview": "{\n  \"version\": 1,\n  \"width\": 102,\n  \"height\": 19,\n  \"duration\": 78.431135,\n  \"command\": null,\n  \"title\": \"ffsend v0.0.9 "
  },
  {
    "path": "res/asciinema-to-svg",
    "chars": 336,
    "preview": "#!/usr/bin/env bash\n\n# Ensure svg-term is installed\nif ! [ -x \"$(command -v svg-term)\" ]; then\n    echo \"svg-term is not"
  },
  {
    "path": "src/action/debug.rs",
    "chars": 4266,
    "preview": "use chrono::Duration;\nuse clap::ArgMatches;\nuse ffsend_api::config::SEND_DEFAULT_EXPIRE_TIME;\nuse prettytable::{format::"
  },
  {
    "path": "src/action/delete.rs",
    "chars": 3045,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::action::delete::{Delete as ApiDelete, Error as DeleteError};\nuse ffsend_api::file:"
  },
  {
    "path": "src/action/download.rs",
    "chars": 14648,
    "preview": "use std::env::current_dir;\nuse std::fs::create_dir_all;\n#[cfg(feature = \"archive\")]\nuse std::io::Error as IoError;\nuse s"
  },
  {
    "path": "src/action/exists.rs",
    "chars": 2558,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::action::exists::{Error as ExistsError, Exists as ApiExists};\nuse ffsend_api::file:"
  },
  {
    "path": "src/action/generate/completions.rs",
    "chars": 1896,
    "preview": "use std::fs;\nuse std::io;\n\nuse clap::ArgMatches;\n\nuse crate::cmd::matcher::{generate::completions::CompletionsMatcher, m"
  },
  {
    "path": "src/action/generate/mod.rs",
    "chars": 957,
    "preview": "pub mod completions;\n\nuse clap::ArgMatches;\n\nuse crate::cmd::matcher::{generate::GenerateMatcher, Matcher};\nuse crate::e"
  },
  {
    "path": "src/action/history.rs",
    "chars": 5233,
    "preview": "use clap::ArgMatches;\nuse failure::Fail;\nuse prettytable::{format::FormatBuilder, Cell, Row, Table};\n\nuse crate::cmd::ma"
  },
  {
    "path": "src/action/info.rs",
    "chars": 6495,
    "preview": "use chrono::Duration;\nuse clap::ArgMatches;\nuse failure::Fail;\nuse ffsend_api::action::exists::{Error as ExistsError, Ex"
  },
  {
    "path": "src/action/mod.rs",
    "chars": 1673,
    "preview": "pub mod debug;\npub mod delete;\npub mod download;\npub mod exists;\npub mod generate;\n#[cfg(feature = \"history\")]\npub mod h"
  },
  {
    "path": "src/action/params.rs",
    "chars": 3057,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::action::params::{Error as ParamsError, Params as ApiParams, ParamsDataBuilder};\nus"
  },
  {
    "path": "src/action/password.rs",
    "chars": 2764,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::action::password::{Error as PasswordError, Password as ApiPassword};\nuse ffsend_ap"
  },
  {
    "path": "src/action/upload.rs",
    "chars": 25022,
    "preview": "use std::env::current_dir;\nuse std::fs;\nuse std::io::{Error as IoError, Write};\nuse std::path::Path;\n#[cfg(feature = \"ar"
  },
  {
    "path": "src/action/version.rs",
    "chars": 1844,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::action::version::{Error as VersionError, Version as ApiVersion};\n\nuse crate::clien"
  },
  {
    "path": "src/archive/archive.rs",
    "chars": 604,
    "preview": "use std::io::{Error as IoError, Read};\nuse std::path::Path;\n\nuse tar::Archive as TarArchive;\n\npub type Result<T> = ::std"
  },
  {
    "path": "src/archive/archiver.rs",
    "chars": 1922,
    "preview": "use std::fs::File;\nuse std::io::{Error as IoError, Write};\nuse std::path::Path;\n\nuse tar::Builder as TarBuilder;\n\npub ty"
  },
  {
    "path": "src/archive/mod.rs",
    "chars": 35,
    "preview": "pub mod archive;\npub mod archiver;\n"
  },
  {
    "path": "src/client.rs",
    "chars": 980,
    "preview": "use std::time::Duration;\n\nuse ffsend_api::client::{ClientConfig, ClientConfigBuilder};\n\nuse crate::cmd::matcher::MainMat"
  },
  {
    "path": "src/cmd/arg/api.rs",
    "chars": 1878,
    "preview": "use clap::{Arg, ArgMatches};\nuse ffsend_api::api::{DesiredVersion, Version};\n\nuse super::{CmdArg, CmdArgOption};\nuse cra"
  },
  {
    "path": "src/cmd/arg/basic_auth.rs",
    "chars": 1233,
    "preview": "use clap::{Arg, ArgMatches};\n\nuse super::{CmdArg, CmdArgOption};\n\n/// The basicauth argument.\npub struct ArgBasicAuth {}"
  },
  {
    "path": "src/cmd/arg/download_limit.rs",
    "chars": 3066,
    "preview": "use clap::{Arg, ArgMatches};\nuse ffsend_api::api::Version as ApiVersion;\nuse ffsend_api::config::downloads_max;\n\nuse sup"
  },
  {
    "path": "src/cmd/arg/expiry_time.rs",
    "chars": 2754,
    "preview": "use chrono::Duration;\nuse clap::{Arg, ArgMatches};\nuse failure::Fail;\nuse ffsend_api::api::Version as ApiVersion;\nuse ff"
  },
  {
    "path": "src/cmd/arg/gen_passphrase.rs",
    "chars": 849,
    "preview": "use chbs;\nuse clap::Arg;\n\nuse super::{CmdArg, CmdArgFlag};\n\n/// The passphrase generation argument.\npub struct ArgGenPas"
  },
  {
    "path": "src/cmd/arg/host.rs",
    "chars": 1116,
    "preview": "use clap::{Arg, ArgMatches};\nuse failure::Fail;\nuse ffsend_api::url::Url;\n\nuse super::{CmdArg, CmdArgOption};\nuse crate:"
  },
  {
    "path": "src/cmd/arg/mod.rs",
    "chars": 1778,
    "preview": "pub mod api;\npub mod basic_auth;\npub mod download_limit;\npub mod expiry_time;\npub mod gen_passphrase;\npub mod host;\npub "
  },
  {
    "path": "src/cmd/arg/owner.rs",
    "chars": 1313,
    "preview": "use clap::{Arg, ArgMatches};\n\nuse super::{CmdArg, CmdArgFlag, CmdArgOption};\nuse crate::cmd::matcher::{MainMatcher, Matc"
  },
  {
    "path": "src/cmd/arg/password.rs",
    "chars": 1371,
    "preview": "use clap::{Arg, ArgMatches};\n\nuse super::{CmdArg, CmdArgFlag, CmdArgOption};\nuse crate::cmd::matcher::{MainMatcher, Matc"
  },
  {
    "path": "src/cmd/arg/url.rs",
    "chars": 957,
    "preview": "use clap::{Arg, ArgMatches};\nuse failure::Fail;\nuse ffsend_api::url::Url;\n\nuse super::{CmdArg, CmdArgOption};\nuse crate:"
  },
  {
    "path": "src/cmd/handler.rs",
    "chars": 10744,
    "preview": "#[cfg(feature = \"infer-command\")]\nuse std::ffi::OsString;\n\nuse clap::{App, AppSettings, Arg, ArgMatches};\n\nuse super::ar"
  },
  {
    "path": "src/cmd/matcher/debug.rs",
    "chars": 732,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::url::Url;\n\nuse super::Matcher;\nuse crate::cmd::arg::{ArgHost, CmdArgOption};\n\n/// "
  },
  {
    "path": "src/cmd/matcher/delete.rs",
    "chars": 945,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::url::Url;\n\nuse super::Matcher;\nuse crate::cmd::arg::{ArgOwner, ArgUrl, CmdArgOptio"
  },
  {
    "path": "src/cmd/matcher/download.rs",
    "chars": 1886,
    "preview": "use std::path::PathBuf;\n\nuse clap::ArgMatches;\nuse ffsend_api::url::Url;\n\nuse super::Matcher;\nuse crate::cmd::arg::{ArgP"
  },
  {
    "path": "src/cmd/matcher/exists.rs",
    "chars": 731,
    "preview": "use ffsend_api::url::Url;\n\nuse clap::ArgMatches;\n\nuse super::Matcher;\nuse crate::cmd::arg::{ArgUrl, CmdArgOption};\n\n/// "
  },
  {
    "path": "src/cmd/matcher/generate/completions.rs",
    "chars": 1826,
    "preview": "use std::path::PathBuf;\nuse std::str::FromStr;\n\nuse clap::{ArgMatches, Shell};\n\nuse super::Matcher;\n\n/// The completions"
  },
  {
    "path": "src/cmd/matcher/generate/mod.rs",
    "chars": 733,
    "preview": "pub mod completions;\n\nuse clap::ArgMatches;\n\nuse super::Matcher;\nuse completions::CompletionsMatcher;\n\n/// The generate "
  },
  {
    "path": "src/cmd/matcher/history.rs",
    "chars": 1256,
    "preview": "use clap::ArgMatches;\nuse failure::Fail;\nuse ffsend_api::url::Url;\n\nuse super::Matcher;\nuse crate::host::parse_host;\nuse"
  },
  {
    "path": "src/cmd/matcher/info.rs",
    "chars": 1128,
    "preview": "use ffsend_api::url::Url;\n\nuse clap::ArgMatches;\n\nuse super::Matcher;\nuse crate::cmd::arg::{ArgOwner, ArgPassword, ArgUr"
  },
  {
    "path": "src/cmd/matcher/main.rs",
    "chars": 3063,
    "preview": "#[cfg(feature = \"history\")]\nuse std::path::PathBuf;\n\nuse clap::ArgMatches;\nuse ffsend_api::api::DesiredVersion;\n\nuse sup"
  },
  {
    "path": "src/cmd/matcher/mod.rs",
    "chars": 925,
    "preview": "pub mod debug;\npub mod delete;\npub mod download;\npub mod exists;\npub mod generate;\n#[cfg(feature = \"history\")]\npub mod h"
  },
  {
    "path": "src/cmd/matcher/params.rs",
    "chars": 1439,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::api::Version as ApiVersion;\nuse ffsend_api::url::Url;\n\nuse super::Matcher;\nuse cra"
  },
  {
    "path": "src/cmd/matcher/password.rs",
    "chars": 2154,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::url::Url;\nuse rpassword::prompt_password_stderr;\n\nuse crate::cmd::arg::{ArgGenPass"
  },
  {
    "path": "src/cmd/matcher/upload.rs",
    "chars": 5648,
    "preview": "use clap::ArgMatches;\nuse ffsend_api::{api::Version as ApiVersion, config, url::Url};\n\nuse super::Matcher;\nuse crate::cm"
  },
  {
    "path": "src/cmd/matcher/version.rs",
    "chars": 741,
    "preview": "use ffsend_api::url::Url;\n\nuse clap::ArgMatches;\n\nuse super::Matcher;\nuse crate::cmd::arg::{ArgHost, CmdArgOption};\n\n///"
  },
  {
    "path": "src/cmd/mod.rs",
    "chars": 116,
    "preview": "pub mod arg;\npub mod handler;\npub mod matcher;\npub mod subcmd;\n\n// Reexport modules\npub use self::handler::Handler;\n"
  },
  {
    "path": "src/cmd/subcmd/debug.rs",
    "chars": 361,
    "preview": "use clap::{App, SubCommand};\n\nuse crate::cmd::arg::{ArgHost, CmdArg};\n\n/// The debug command definition.\npub struct CmdD"
  },
  {
    "path": "src/cmd/subcmd/delete.rs",
    "chars": 427,
    "preview": "use clap::{App, SubCommand};\n\nuse crate::cmd::arg::{ArgOwner, ArgUrl, CmdArg};\n\n/// The delete command definition.\npub s"
  },
  {
    "path": "src/cmd/subcmd/download.rs",
    "chars": 1281,
    "preview": "use clap::{App, Arg, SubCommand};\n\nuse crate::cmd::arg::{ArgPassword, ArgUrl, CmdArg};\n\n/// The download command definit"
  },
  {
    "path": "src/cmd/subcmd/exists.rs",
    "chars": 388,
    "preview": "use clap::{App, SubCommand};\n\nuse crate::cmd::arg::{ArgUrl, CmdArg};\n\n/// The exists command definition.\npub struct CmdE"
  },
  {
    "path": "src/cmd/subcmd/generate/completions.rs",
    "chars": 1097,
    "preview": "use clap::{App, Arg, Shell, SubCommand};\n\n/// The generate completions command definition.\npub struct CmdCompletions;\n\ni"
  },
  {
    "path": "src/cmd/subcmd/generate/mod.rs",
    "chars": 457,
    "preview": "pub mod completions;\n\nuse clap::{App, AppSettings, SubCommand};\n\nuse completions::CmdCompletions;\n\n/// The generate comm"
  },
  {
    "path": "src/cmd/subcmd/history.rs",
    "chars": 786,
    "preview": "use clap::{App, Arg, SubCommand};\n\n/// The history command definition.\npub struct CmdHistory;\n\nimpl CmdHistory {\n    pub"
  },
  {
    "path": "src/cmd/subcmd/info.rs",
    "chars": 480,
    "preview": "use clap::{App, SubCommand};\n\nuse crate::cmd::arg::{ArgOwner, ArgPassword, ArgUrl, CmdArg};\n\n/// The info command defini"
  },
  {
    "path": "src/cmd/subcmd/mod.rs",
    "chars": 638,
    "preview": "pub mod debug;\npub mod delete;\npub mod download;\npub mod exists;\npub mod generate;\n#[cfg(feature = \"history\")]\npub mod h"
  },
  {
    "path": "src/cmd/subcmd/params.rs",
    "chars": 698,
    "preview": "use clap::{App, SubCommand};\n\nuse crate::cmd::arg::{ArgDownloadLimit, ArgOwner, ArgUrl, CmdArg};\n\n/// The params command"
  },
  {
    "path": "src/cmd/subcmd/password.rs",
    "chars": 607,
    "preview": "use clap::{App, SubCommand};\n\nuse crate::cmd::arg::{ArgGenPassphrase, ArgOwner, ArgPassword, ArgUrl, CmdArg};\n\n/// The p"
  },
  {
    "path": "src/cmd/subcmd/upload.rs",
    "chars": 3519,
    "preview": "use clap::{App, Arg, SubCommand};\n\nuse crate::cmd::arg::{\n    ArgDownloadLimit, ArgExpiryTime, ArgGenPassphrase, ArgHost"
  },
  {
    "path": "src/cmd/subcmd/version.rs",
    "chars": 391,
    "preview": "use clap::{App, SubCommand};\n\nuse crate::cmd::arg::{ArgHost, CmdArg};\n\n/// The version command definition.\npub struct Cm"
  },
  {
    "path": "src/config.rs",
    "chars": 1426,
    "preview": "#[cfg(feature = \"infer-command\")]\nuse std::collections::HashMap;\n\nuse ffsend_api::api::{DesiredVersion, Version};\n\n/// T"
  },
  {
    "path": "src/error.rs",
    "chars": 4324,
    "preview": "use ffsend_api::action::delete::Error as DeleteError;\nuse ffsend_api::action::exists::Error as ExistsError;\nuse ffsend_a"
  },
  {
    "path": "src/history.rs",
    "chars": 10508,
    "preview": "use std::fs;\nuse std::io::Error as IoError;\nuse std::path::PathBuf;\n\nuse failure::Fail;\nuse ffsend_api::{\n    file::remo"
  },
  {
    "path": "src/history_tool.rs",
    "chars": 4506,
    "preview": "use failure::Fail;\nuse ffsend_api::file::remote_file::RemoteFile;\n\nuse crate::cmd::matcher::MainMatcher;\nuse crate::hist"
  },
  {
    "path": "src/host.rs",
    "chars": 1883,
    "preview": "use ffsend_api::url::{ParseError, Url};\n\n/// Parse the given host string, into an URL.\npub fn parse_host(host: &str) -> "
  },
  {
    "path": "src/main.rs",
    "chars": 4879,
    "preview": "#[macro_use]\nextern crate clap;\n#[macro_use]\nextern crate derive_builder;\n#[macro_use]\nextern crate failure;\n#[macro_use"
  },
  {
    "path": "src/progress.rs",
    "chars": 2158,
    "preview": "use std::io::{stderr, Stderr};\nuse std::time::Duration;\n\nuse ffsend_api::pipe::ProgressReporter;\nuse pbr::{ProgressBar a"
  },
  {
    "path": "src/urlshorten.rs",
    "chars": 2981,
    "preview": "//! URL shortening mechanics.\n\nuse ffsend_api::{\n    api::request::{ensure_success, ResponseError},\n    client::Client,\n"
  },
  {
    "path": "src/util.rs",
    "chars": 34925,
    "preview": "#[cfg(feature = \"clipboard-crate\")]\nextern crate clip;\n#[cfg(feature = \"clipboard-bin\")]\nextern crate which;\n\nuse std::b"
  }
]

About this extraction

This page contains the full source code of the timvisee/ffsend GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 101 files (637.0 KB), approximately 157.6k tokens, and a symbol index with 379 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!