;; SPDX-License-Identifier: BSD-2-Clause ;; Platform-specific code (shall we say - not specified by POSIX). ;; Until otherwise specified, the platform is assumed to be FreeBSD ;; (base, no third-party packages installed). ;; why sha512t256? "On 64-bit hardware, this algorithm is ;; approximately 50% faster than SHA-256 but with the same level of ;; security..." -- md5(1) (defun crypto-digests filenames (let ((command (append '("sha512t256" "-q") filenames))) (or (apply output-lines-of command) (error "no output from command %s" (repr command))))) (defun crypto-digest (filename) (some-output-or-error "sha512t256" "-q" filename)) ;; see probe-sed-crypto-digest (defun pipe-crypto-digest () (list :pipe "sha512t256" "-q")) ;; -r: random (version 4) UUID (defun get-new-uuid () (some-output-or-error "uuidgen" "-r")) ;; %z: size in bytes (st_size). GNU and Busybox use %s for that, but ;; FreeBSD stat says "bad format" about %s. (defun get-size-of-file (filename) (as-number (some-output-or-error "stat" "-f" "%z" filename))) ;; maybe we could do some other checks on this, but nonempty should ;; suffice to begin with (defun make-temp-filename-from (based-on-path) (some-output-or-error "mktemp" (sprintf "%s.XXXXXXXX" based-on-path))) (defun get-ogm (source-path) ;; The jail has its own set of users, so to get the owner and group ;; of a file as names, we have to run stat inside the jail, so it ;; will query the right passwd file. (The alternative is to use only ;; numeric uids and gids everywhere; but some users and groups are ;; just created with the next available id, including some created ;; by packages; so you can't know their numeric ids ahead of time.) (let ((user (apply some-output-or-error (*run-in-chroot* "stat" "-f" "%Su" source-path))) (group (apply some-output-or-error (*run-in-chroot* "stat" "-f" "%Sg" source-path))) ;; Lp: "low perms." user, group, and other bits from perms, ;; but not file type bits. this will be an octal number; let ;; us not treat it as a decimal number. (mode (some-output-or-error "stat" "-f" "%Lp" source-path))) (list user group mode))) (defun set-ogm (dest-path user group mode) ;; Likewise, in order to consume the right mapping of users to ;; numeric uids, we have to run the chown and chmod inside the jail ;; and pass the unmodified path. (apply system-or-error (*run-in-chroot* "chown" (sprintf "%s:%s" user group) dest-path)) (apply system-or-error (*run-in-chroot* "chmod" mode dest-path))) ;; for GNU, you could chown --reference and chmod --reference (defun copy-ogm (source-path dest-path) (apply set-ogm dest-path (get-ogm source-path)))