Logo

dev-resources.site

for different kinds of informations.

FTP and SFTP clients for Common Lisp

Published at
9/28/2024
Categories
lisp
commonlisp
sftp
Author
vindarel
Categories
3 categories in total
lisp
open
commonlisp
open
sftp
open
Author
8 person written this
vindarel
open
FTP and SFTP clients for Common Lisp

You thought all companies would provide well-documented web APIs today? Well, some use a blank .docx and (S)FTP.

For Common Lisp, cl-ftp is one of those libraries that look unmaintained and undocumented, but it works very well, and it is short enough to quickly grab how to use it. It's quite well thought-out, even. It is a pure Lisp library, no system dependencies required.

For example you can do this to send a file:

(ftp:with-ftp-connection (conn :hostname hostname
                                   :username (find-ftp-username)
                                   :password password
                                   :passive-ftp-p t)
      (ftp:store-file conn local-filename filename))
Enter fullscreen mode Exit fullscreen mode

You'll have to look at this for more commands: https://github.com/pinterface/cl-ftp/blob/master/simple-client.lisp

we have ftp-shell, ftp-put, ftp-list, ftp-get, ftp-pwd, and etc for ls, help, cd, dir.

For SFTP, we must find another means. I didn't find a pure CL library, and it is annoyingly not straightforward to run a SFTP command with a password on the command line. Some solutions exist and I chose lftp. It is included in Debian.

We can run:

lftp sftp://user:password@host  -e "put local-file.name; bye"
Enter fullscreen mode Exit fullscreen mode

or better, with the password in an environment variable:

export LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user@host  -e "put local-file.name; bye"
Enter fullscreen mode Exit fullscreen mode

In my scripts I need to handle a connection profile, and even several ones for development, so I ended up with code that I replicate from project to project, hence a new utility:

https://github.com/vindarel/lftp-wrapper

Now do:

CL-USER> (use-package :lftp-wrapper)  ;; optional, or:
CL-USER> (uiop:add-package-local-nickname :lftp :lftp-wrapper)

CL-USER> (defvar profile (make-profile-from-plist (uiop:read-file-form "CREDS.lisp-expr"))
#<PROFILE protocol: "sftp", login: "user", port: 10022, server: "prod.com", password? T>

CL-USER> (defvar command (put :cd "I/" :local-filename "data.csv"))
#<PUT cd: "I/", filename: "data.csv" {1007153883}>

CL-USER> (run profile command)
โ€ฆ
success!
Enter fullscreen mode Exit fullscreen mode

We created a profile from credentials on file and from environment variables, we created a command object, and we executed the command for the profile.

We could wrap many more features from lftp. But I follow needs-driven development. So far, it works and it sends my files.

lisp Article's
30 articles in total
Favicon
Common Lisp HTML templates: using Djula in .lisp files
Favicon
Remaking a rule-engine DSL
Favicon
Advent of Code: alexandria's map-permutations was perfect for day 08. Common Lisp tip.
Favicon
C and C++ are really so fast?
Favicon
Scheming About Clojure
Favicon
FTP and SFTP clients for Common Lisp
Favicon
Common Lisp with batteries included: CIEL v0.2 (aka fast scripting with useful libraries)
Favicon
A shell script that I usually run after installing SBCL
Favicon
Common Lisp VS Haskell
Favicon
Debugging Common Lisp: "Iย feel so much faster and free"
Favicon
Learning Lisp - making sense of xrefs in SLIME
Favicon
Learning Lisp
Favicon
Common Lisp's groupBy is Serapeum:assort
Favicon
Common Lisp VS C: a testimony
Favicon
Lisp: simplifying my problems through code
Favicon
Python VS Common Lisp applied: print, log and icecream
Favicon
Lisp-style list in Rust
Favicon
RainLisp on .NET
Favicon
Is Elixir or Common Lisp the best language for building a bootstrapped B2B SaaS in 2024?
Favicon
Form validation in Common Lisp
Favicon
Common Lisp GUI with Electron ยท quick how to
Favicon
Throttle/debounce a Common Lisp function
Favicon
OOP via FP : functional nature of classes and objects
Favicon
5 ways to get text from an Emacs buffer
Favicon
Configuring Neovim with Fennel
Favicon
Coding in the Shadows: Hidden Gems of Lisp, Clojure, and Friends
Favicon
Emacs is More Like a Terminal Than an Editor
Favicon
Do you need an IDE to write Common Lisp?
Favicon
Entendendo Algoritmos - Cap.5 Quicksort em Clojure
Favicon
The unreasonable effectiveness of working with a live programming image

Featured ones: