Eric Bower
·
2026-05-31
1package rsyncreceiver
2
3import (
4 "io"
5)
6
7type mapping struct {
8 Name string
9 LocalId int32
10}
11
12func (rt *Transfer) recvIdMapping1(localId func(id int32, name string) int32) (map[int32]mapping, error) {
13 idMapping := make(map[int32]mapping)
14 for {
15 id, err := rt.Conn.ReadInt32()
16 if err != nil {
17 return nil, err
18 }
19 if id == 0 {
20 break
21 }
22 length, err := rt.Conn.ReadByte()
23 if err != nil {
24 return nil, err
25 }
26 name := make([]byte, length)
27 if _, err := io.ReadFull(rt.Conn.Reader, name); err != nil {
28 return nil, err
29 }
30 idMapping[id] = mapping{
31 Name: string(name),
32 LocalId: localId(id, string(name)),
33 }
34 }
35 return idMapping, nil
36}
37
38// rsync/uidlist.c:recv_id_list.
39func (rt *Transfer) RecvIdList() (users map[int32]mapping, groups map[int32]mapping, _ error) {
40 if rt.Opts.PreserveUid {
41 var err error
42 users, err = rt.recvIdMapping1(func(remoteUid int32, remoteUsername string) int32 {
43 // TODO: look up local uid by username
44 return remoteUid
45 })
46 if err != nil {
47 return nil, nil, err
48 }
49 for remoteUid, mapping := range users {
50 rt.Logger.Debug("remote uid maps to local uid", "remoteUid", remoteUid, "name", mapping.Name, "localUid", mapping.LocalId)
51 }
52 }
53
54 if rt.Opts.PreserveGid {
55 var err error
56 groups, err = rt.recvIdMapping1(func(remoteGid int32, remoteGroupname string) int32 {
57 // TODO: look up local gid by groupname
58 return remoteGid
59 })
60 if err != nil {
61 return nil, nil, err
62 }
63 for remoteGid, mapping := range groups {
64 rt.Logger.Debug("remote gid maps to local gid", "remoteGid", remoteGid, "name", mapping.Name, "localGid", mapping.LocalId)
65 }
66 }
67
68 return users, groups, nil
69}