main pico / pkg / rsync-receiver / utils / file.go
Eric Bower  ·  2026-05-31
 1package utils
 2
 3import (
 4	"io"
 5	"io/fs"
 6	"sort"
 7	"time"
 8
 9	"github.com/picosh/pico/pkg/rsync-receiver/rsync"
10)
11
12type SenderFile struct {
13	// TODO: store relative to the root to conserve RAM
14	Path    string
15	WPath   string
16	Regular bool
17}
18
19type ReceiverFile struct {
20	Name       string
21	Length     int64
22	ModTime    time.Time
23	Mode       int32
24	Uid        int32
25	Gid        int32
26	LinkTarget string
27	Rdev       int32
28	Reader     io.Reader
29}
30
31// FileMode converts from the Linux permission bits to Go’s permission bits.
32func (f *ReceiverFile) FileMode() fs.FileMode {
33	ret := fs.FileMode(f.Mode) & fs.ModePerm
34
35	mode := f.Mode & rsync.S_IFMT
36	switch mode {
37	case rsync.S_IFCHR:
38		ret |= fs.ModeCharDevice
39	case rsync.S_IFBLK:
40		ret |= fs.ModeDevice
41	case rsync.S_IFIFO:
42		ret |= fs.ModeNamedPipe
43	case rsync.S_IFSOCK:
44		ret |= fs.ModeSocket
45	case rsync.S_IFLNK:
46		ret |= fs.ModeSymlink
47	case rsync.S_IFDIR:
48		ret |= fs.ModeDir
49	}
50
51	return ret
52}
53
54// rsync/flist.c:flist_sort_and_clean.
55func SortFileList(fileList []*ReceiverFile) {
56	sort.Slice(fileList, func(i, j int) bool {
57		return fileList[i].Name < fileList[j].Name
58	})
59}
60
61// rsync/receiver.c:delete_files.
62func FindInFileList(fileList []*ReceiverFile, name string) bool {
63	i := sort.Search(len(fileList), func(i int) bool {
64		return fileList[i].Name >= name
65	})
66	return i < len(fileList) && fileList[i].Name == name
67}