1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #define MKID(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
20 
21 #define ID_LSTAT_V1 MKID('S', 'T', 'A', 'T')
22 #define ID_STAT_V2 MKID('S', 'T', 'A', '2')
23 #define ID_LSTAT_V2 MKID('L', 'S', 'T', '2')
24 
25 #define ID_LIST_V1 MKID('L', 'I', 'S', 'T')
26 #define ID_LIST_V2 MKID('L', 'I', 'S', '2')
27 #define ID_DENT_V1 MKID('D', 'E', 'N', 'T')
28 #define ID_DENT_V2 MKID('D', 'N', 'T', '2')
29 
30 #define ID_SEND_V1 MKID('S', 'E', 'N', 'D')
31 #define ID_SEND_V2 MKID('S', 'N', 'D', '2')
32 #define ID_RECV_V1 MKID('R', 'E', 'C', 'V')
33 #define ID_RECV_V2 MKID('R', 'C', 'V', '2')
34 #define ID_DONE MKID('D', 'O', 'N', 'E')
35 #define ID_DATA MKID('D', 'A', 'T', 'A')
36 #define ID_OKAY MKID('O', 'K', 'A', 'Y')
37 #define ID_FAIL MKID('F', 'A', 'I', 'L')
38 #define ID_QUIT MKID('Q', 'U', 'I', 'T')
39 
40 struct SyncRequest {
41     uint32_t id;           // ID_STAT, et cetera.
42     uint32_t path_length;  // <= 1024
43     // Followed by 'path_length' bytes of path (not NUL-terminated).
44 } __attribute__((packed));
45 
46 struct __attribute__((packed)) sync_stat_v1 {
47     uint32_t id;
48     uint32_t mode;
49     uint32_t size;
50     uint32_t mtime;
51 };
52 
53 struct __attribute__((packed)) sync_stat_v2 {
54     uint32_t id;
55     uint32_t error;
56     uint64_t dev;
57     uint64_t ino;
58     uint32_t mode;
59     uint32_t nlink;
60     uint32_t uid;
61     uint32_t gid;
62     uint64_t size;
63     int64_t atime;
64     int64_t mtime;
65     int64_t ctime;
66 };
67 
68 struct __attribute__((packed)) sync_dent_v1 {
69     uint32_t id;
70     uint32_t mode;
71     uint32_t size;
72     uint32_t mtime;
73     uint32_t namelen;
74 };  // followed by `namelen` bytes of the name.
75 
76 struct __attribute__((packed)) sync_dent_v2 {
77     uint32_t id;
78     uint32_t error;
79     uint64_t dev;
80     uint64_t ino;
81     uint32_t mode;
82     uint32_t nlink;
83     uint32_t uid;
84     uint32_t gid;
85     uint64_t size;
86     int64_t atime;
87     int64_t mtime;
88     int64_t ctime;
89     uint32_t namelen;
90 };  // followed by `namelen` bytes of the name.
91 
92 enum SyncFlag : uint32_t {
93     kSyncFlagNone = 0,
94     kSyncFlagBrotli = 1,
95     kSyncFlagLZ4 = 2,
96     kSyncFlagZstd = 4,
97     kSyncFlagDryRun = 0x8000'0000U,
98 };
99 
100 enum class CompressionType {
101     None,
102     Any,
103     Brotli,
104     LZ4,
105     Zstd,
106 };
107 
108 // send_v1 sent the path in a buffer, followed by a comma and the mode as a string.
109 // send_v2 sends just the path in the first request, and then sends another syncmsg (with the
110 // same ID!) with details.
111 struct __attribute__((packed)) sync_send_v2 {
112     uint32_t id;
113     uint32_t mode;
114     uint32_t flags;
115 };
116 
117 // Likewise, recv_v1 just sent the path without any accompanying data.
118 struct __attribute__((packed)) sync_recv_v2 {
119     uint32_t id;
120     uint32_t flags;
121 };
122 
123 struct __attribute__((packed)) sync_data {
124     uint32_t id;
125     uint32_t size;
126 };  // followed by `size` bytes of data.
127 
128 struct __attribute__((packed)) sync_status {
129     uint32_t id;
130     uint32_t msglen;
131 };  // followed by `msglen` bytes of error message, if id == ID_FAIL.
132 
133 union syncmsg {
134     sync_stat_v1 stat_v1;
135     sync_stat_v2 stat_v2;
136     sync_dent_v1 dent_v1;
137     sync_dent_v2 dent_v2;
138     sync_data data;
139     sync_status status;
140     sync_send_v2 send_v2_setup;
141     sync_recv_v2 recv_v2_setup;
142 };
143 
144 #define SYNC_DATA_MAX (64 * 1024)
145