From e1a5da3426a7dce085c73ec346059fdd4a758f66 Mon Sep 17 00:00:00 2001 From: Lassi Kortela Date: Sat, 22 Jun 2019 22:30:44 +0300 Subject: [PATCH] Initial commit --- lassik/trivial-tar-writer.scm | 54 +++++++++++++++++++++++++++++++++++ lassik/trivial-tar-writer.sld | 6 ++++ 2 files changed, 60 insertions(+) create mode 100644 lassik/trivial-tar-writer.scm create mode 100644 lassik/trivial-tar-writer.sld diff --git a/lassik/trivial-tar-writer.scm b/lassik/trivial-tar-writer.scm new file mode 100644 index 0000000..6815f45 --- /dev/null +++ b/lassik/trivial-tar-writer.scm @@ -0,0 +1,54 @@ +;;; Copyright (c) 2019 Lassi Kortela +;;; SPDX-License-Identifier: ISC + +(define nulls (make-bytevector 512 0)) +(define zeros (make-bytevector 12 (char->integer #\0))) + +(define (tar-poke-string header at nbyte string) + (let* ((bytes (string->utf8 string)) + (nnull (- nbyte (bytevector-length bytes)))) + (when (< nnull 0) (error "tar: string too long")) + (bytevector-copy! header at bytes))) + +(define (tar-poke-octal header at nbyte number) + (unless (integer? number) (error "tar: not an integer")) + (when (< number 0) (error "tar: negative integer")) + (let* ((bytes (string->utf8 (number->string number 8))) + (nzero (- nbyte 1 (bytevector-length bytes)))) + (when (< nzero 0) (error "tar: number too big")) + (bytevector-copy! header at zeros 0 nzero) + (bytevector-copy! header (+ at nzero) bytes) + (bytevector-u8-set! header (+ at nbyte -1) 0))) + +(define (tar-header-checksum header) + (let ((n (bytevector-length header))) + (let loop ((i 0) (sum 0)) + (if (= i n) + (truncate-remainder sum (expt 8 6)) + (loop (+ i 1) (+ sum (bytevector-u8-ref header i))))))) + +(define (tar-write-file fake-path bytes) + (let* ((header (make-bytevector 512 0)) + (nbyte (bytevector-length bytes)) + (nnull (- 512 (truncate-remainder nbyte 512))) + (unix-time-now 0)) + (tar-poke-string header 0 100 fake-path) + (tar-poke-octal header 100 8 #o644) + (tar-poke-octal header 108 8 0) + (tar-poke-octal header 116 8 0) + (tar-poke-octal header 124 12 nbyte) + (tar-poke-octal header 136 12 unix-time-now) + (bytevector-copy! header 148 (make-bytevector 8 (char->integer #\space))) + (bytevector-u8-set! header 156 (char->integer #\0)) + (tar-poke-string header 157 100 "") + (tar-poke-string header 257 8 "ustar ") + (tar-poke-string header 265 32 "root") + (tar-poke-string header 297 32 "root") + (tar-poke-octal header 148 7 (tar-header-checksum header)) + (write-bytevector header) + (write-bytevector bytes) + (write-bytevector nulls (current-output-port) 0 nnull))) + +(define (tar-poke-end) + (write-bytevector nulls) + (write-bytevector nulls)) diff --git a/lassik/trivial-tar-writer.sld b/lassik/trivial-tar-writer.sld new file mode 100644 index 0000000..3d820c4 --- /dev/null +++ b/lassik/trivial-tar-writer.sld @@ -0,0 +1,6 @@ +(define-library (trivial-tar-writer) + (export tar-write-file) + (import (scheme base) + (scheme char) + (scheme write)) + (include "trivial-tar-writer.scm"))