billyconv.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package billyconv
  2. /*
  3. Billy Filesystem Converter
  4. This module converts an arozfs file system into a Billy Filesystem
  5. used by many other projects for providing a vfs interface
  6. */
  7. import (
  8. "errors"
  9. "io/fs"
  10. "os"
  11. "path/filepath"
  12. "github.com/go-git/go-billy/v5"
  13. "imuslab.com/arozos/mod/filesystem"
  14. "imuslab.com/arozos/mod/filesystem/arozfs"
  15. )
  16. //This script adapts the required billy.FileSystem to arozos abstraction
  17. type ArozFsToBillyFileSytemAdapter struct {
  18. fsh *filesystem.FileSystemHandler
  19. }
  20. func NewArozFsToBillyFsAdapter(targetFsh *filesystem.FileSystemHandler) billy.Filesystem {
  21. return &ArozFsToBillyFileSytemAdapter{
  22. fsh: targetFsh,
  23. }
  24. }
  25. func (adp *ArozFsToBillyFileSytemAdapter) Create(filename string) (billy.File, error) {
  26. filename = adp.CleanAndFilterFilename(filename)
  27. file, err := adp.fsh.FileSystemAbstraction.Create(filename)
  28. if err != nil {
  29. return nil, err
  30. }
  31. return ArozfsFileToBillyFile(file), nil
  32. }
  33. func (adp *ArozFsToBillyFileSytemAdapter) Open(filename string) (billy.File, error) {
  34. filename = adp.CleanAndFilterFilename(filename)
  35. file, err := adp.fsh.FileSystemAbstraction.Open(filename)
  36. if err != nil {
  37. return nil, err
  38. }
  39. return ArozfsFileToBillyFile(file), nil
  40. }
  41. func (adp *ArozFsToBillyFileSytemAdapter) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
  42. filename = adp.CleanAndFilterFilename(filename)
  43. file, err := adp.fsh.FileSystemAbstraction.OpenFile(filename, flag, perm)
  44. if err != nil {
  45. return nil, err
  46. }
  47. return ArozfsFileToBillyFile(file), nil
  48. }
  49. func (adp *ArozFsToBillyFileSytemAdapter) Stat(filename string) (os.FileInfo, error) {
  50. filename = adp.CleanAndFilterFilename(filename)
  51. fileInfo, err := adp.fsh.FileSystemAbstraction.Stat(filename)
  52. if err != nil {
  53. return nil, err
  54. }
  55. return ConvertToOsFileInfo(fileInfo), err
  56. }
  57. func (adp *ArozFsToBillyFileSytemAdapter) Rename(oldpath, newpath string) error {
  58. oldpath = adp.CleanAndFilterFilename(oldpath)
  59. newpath = adp.CleanAndFilterFilename(newpath)
  60. return adp.Rename(oldpath, newpath)
  61. }
  62. func (adp *ArozFsToBillyFileSytemAdapter) Remove(filename string) error {
  63. filename = adp.CleanAndFilterFilename(filename)
  64. return adp.fsh.FileSystemAbstraction.Remove(filename)
  65. }
  66. func (adp *ArozFsToBillyFileSytemAdapter) Join(elem ...string) string {
  67. return filepath.Join(elem...)
  68. }
  69. func (adp *ArozFsToBillyFileSytemAdapter) TempFile(dir, prefix string) (billy.File, error) {
  70. return nil, errors.New("operation not supported")
  71. }
  72. func (adp *ArozFsToBillyFileSytemAdapter) ReadDir(path string) ([]os.FileInfo, error) {
  73. path = adp.CleanAndFilterFilename(path)
  74. dirEntry, err := adp.fsh.FileSystemAbstraction.ReadDir(path)
  75. if err != nil {
  76. return []os.FileInfo{}, err
  77. }
  78. fileInfo, err := ConvertDirEntriesToFileInfos(dirEntry)
  79. if err != nil {
  80. return []os.FileInfo{}, err
  81. }
  82. return fileInfo, nil
  83. }
  84. func (adp *ArozFsToBillyFileSytemAdapter) MkdirAll(filename string, perm os.FileMode) error {
  85. filename = adp.CleanAndFilterFilename(filename)
  86. return adp.fsh.FileSystemAbstraction.MkdirAll(filename, perm)
  87. }
  88. func (adp *ArozFsToBillyFileSytemAdapter) Lstat(filename string) (os.FileInfo, error) {
  89. return nil, errors.New("operation not supported")
  90. }
  91. func (adp *ArozFsToBillyFileSytemAdapter) Symlink(target, link string) error {
  92. return errors.New("operation not supported")
  93. }
  94. func (adp *ArozFsToBillyFileSytemAdapter) Readlink(link string) (string, error) {
  95. return "", errors.New("operation not supported")
  96. }
  97. func (adp *ArozFsToBillyFileSytemAdapter) Chroot(path string) (billy.Filesystem, error) {
  98. return nil, errors.New("operation not supported")
  99. }
  100. func (adp *ArozFsToBillyFileSytemAdapter) Root() string {
  101. return "/"
  102. }
  103. /* Utilities */
  104. func (adp *ArozFsToBillyFileSytemAdapter) CleanAndFilterFilename(filename string) string {
  105. return filename
  106. }
  107. /*
  108. arozfs.File to Billy.File converter
  109. */
  110. type ArozFSFileAdapter struct {
  111. file arozfs.File
  112. }
  113. func ArozfsFileToBillyFile(file arozfs.File) billy.File {
  114. return &ArozFSFileAdapter{
  115. file: file,
  116. }
  117. }
  118. func (afa *ArozFSFileAdapter) Name() string {
  119. return afa.file.Name()
  120. }
  121. func (afa *ArozFSFileAdapter) Read(b []byte) (int, error) {
  122. return afa.file.Read(b)
  123. }
  124. func (afa *ArozFSFileAdapter) ReadAt(b []byte, off int64) (int, error) {
  125. return afa.file.ReadAt(b, off)
  126. }
  127. func (afa *ArozFSFileAdapter) Seek(offset int64, whence int) (int64, error) {
  128. return afa.file.Seek(offset, whence)
  129. }
  130. func (afa *ArozFSFileAdapter) Write(b []byte) (int, error) {
  131. return afa.file.Write(b)
  132. }
  133. func (afa *ArozFSFileAdapter) Lock() error {
  134. return nil
  135. }
  136. func (afa *ArozFSFileAdapter) Unlock() error {
  137. return nil
  138. }
  139. func (afa *ArozFSFileAdapter) Truncate(size int64) error {
  140. return errors.New("operation not supported")
  141. }
  142. func (afa *ArozFSFileAdapter) Close() error {
  143. return afa.file.Close()
  144. }
  145. /*
  146. */
  147. // Define a type that wraps an fs.FileInfo and implements os.FileInfo
  148. type fileInfoWrapper struct {
  149. fs.FileInfo
  150. }
  151. // Implement the Sys method to satisfy os.FileInfo
  152. func (f fileInfoWrapper) Sys() interface{} {
  153. return nil
  154. }
  155. // Convert fs.FileInfo to os.FileInfo
  156. func ConvertToOsFileInfo(fi fs.FileInfo) os.FileInfo {
  157. return fileInfoWrapper{fi}
  158. }
  159. // Convert []fs.DirEntry to []os.FileInfo
  160. func ConvertDirEntriesToFileInfos(entries []fs.DirEntry) ([]os.FileInfo, error) {
  161. var fileInfos []os.FileInfo
  162. for _, entry := range entries {
  163. info, err := entry.Info()
  164. if err != nil {
  165. return nil, err
  166. }
  167. fileInfos = append(fileInfos, ConvertToOsFileInfo(info))
  168. }
  169. return fileInfos, nil
  170. }