From 8e97bd5a1e47d525f240741316c2245179e95937 Mon Sep 17 00:00:00 2001 From: Eitaro Fukamachi Date: Wed, 9 Oct 2024 08:42:25 +0000 Subject: [PATCH] Add `sftp-put` for writing a file via SFTP. --- src/package.lisp | 1 + src/sftp.lisp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/package.lisp b/src/package.lisp index 4251ad8..0c6251b 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -55,6 +55,7 @@ :sftp-list-directory :sftp-get :sftp-delete + :sftp-put ;; STREAMS API // BLOCKING diff --git a/src/sftp.lisp b/src/sftp.lisp index 54ca974..4c92116 100644 --- a/src/sftp.lisp +++ b/src/sftp.lisp @@ -83,3 +83,20 @@ It is possible to combine `MAXFILES' and `EXTENSIONS' (retrieve 5 files with ext (ssh2.debug "Trying to delete remote file ~A" remote-path) (let ((result (libssh2-sftp-unlink-ex sftp remote-path))) (ssh2.debug "Deleting ~A resulted in ~A." remote-path result)))) + +(defun sftp-put (ssh-connection local-path remote-path) + (with-sftp (sftp ssh-connection) + (let ((handle)) + (unwind-protect + (progn + (ssh2.debug "Trying to send local file ~A to remote file ~A" local-path remote-path) + (setf handle (libssh2-sftp-open-ex sftp remote-path (foreign-bitfield-value 'sftp-flags '(:write :creat :trunc)) + #o644 + :file)) + (with-open-file (in local-path :direction :input :element-type '(unsigned-byte 8)) + (let ((buffer (make-array 1024 :element-type '(unsigned-byte 8)))) + (loop for numbytes = (read-sequence buffer in) + until (zerop numbytes) + do (cffi:with-foreign-array (array buffer `(:array :uint8 ,numbytes)) (libssh2-sftp-write handle array numbytes))))) + (ssh2.debug "Local file ~A was written to ~A" local-path remote-path))) + (when handle (libssh2-sftp-close-handle handle)))))