zip-translator.lisp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. (defpackage :zip-translator
  2. (:use :cl :hurd-common :mach
  3. :hurd :hurd-translator
  4. :zip))
  5. (in-package :zip-translator)
  6. (defclass zip-translator (translator)
  7. ()
  8. (:documentation "Zip translators zips the target directory and exposes the translated node as a zip file."))
  9. (defun temporary-file-name ()
  10. (format nil "zip-translator-~A.zip" (random 50000)))
  11. (defconstant +target-dir+ (first ext:*args*))
  12. (defconstant +zip-file+ (temporary-file-name))
  13. (defconstant +zip-file-path+ (concatenate-string "/tmp/" +zip-file+))
  14. ;; Zip target target directory.
  15. (warn "Zipping directory ~A to ~A" +target-dir+ +zip-file+)
  16. (zip +zip-file-path+ +target-dir+)
  17. (warn "Zip of directory ~A done." +target-dir+)
  18. (defvar *zip-port* (file-name-lookup +zip-file-path+ :flags '(:read)))
  19. ;; Remove file when clisp exits.
  20. (push (lambda ()
  21. (port-deallocate *zip-port*)
  22. (with-port-deallocate (port (file-name-lookup "/tmp" :flags '(:read)))
  23. (dir-unlink port +zip-file+)))
  24. custom:*fini-hooks*)
  25. (define-callback allow-open-p zip-translator
  26. (node user flags is-new-p)
  27. (declare (ignore is-new-p))
  28. (when (flag-is-p flags :write)
  29. (return-from allow-open-p nil))
  30. (when (flag-is-p flags :read)
  31. (unless (has-access-p node user :read)
  32. (return-from allow-open-p nil)))
  33. t)
  34. (define-callback report-access zip-translator
  35. (node user)
  36. (let ((ret))
  37. (when (has-access-p node user :read)
  38. (push :read ret))
  39. ret))
  40. (define-callback read-file zip-translator
  41. (node user start amount stream)
  42. (when (has-access-p node user :read)
  43. (let ((data (io-read *zip-port*
  44. :amount amount
  45. :offset start)))
  46. (when data
  47. (write-sequence data stream)
  48. t))))
  49. (define-callback make-root-node zip-translator
  50. (underlying-node underlying-stat)
  51. (declare (ignore underlying-node))
  52. (let ((mode (make-mode :perms '((:owner :read)
  53. (:group :read)
  54. (:others :read))
  55. :type :reg))
  56. (stat (io-stat *zip-port*)))
  57. (make-instance 'node
  58. :stat (make-stat underlying-stat
  59. :mode mode
  60. :size (stat-get stat 'st-size)))))
  61. (defun main ()
  62. (run-translator (make-instance 'zip-translator
  63. :name "zip-translator"
  64. :version (list 0 0 1))))
  65. (main)