diff --git a/go.mod b/go.mod index da7382c24c5..275b1251fe7 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/mod v0.5.1 // indirect golang.org/x/net v0.0.0-20220607020251-c690dde0001d - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a + golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b golang.org/x/text v0.3.7 golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac golang.org/x/tools v0.1.7 diff --git a/go.sum b/go.sum index 2ea520cea7d..d912a1bf487 100644 --- a/go.sum +++ b/go.sum @@ -603,8 +603,9 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b h1:2n253B2r0pYSmEV+UNCQoPfU/FiaizQEK5Gu4Bq4JE8= +golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/lib/config/config.pb.go b/lib/config/config.pb.go index 12a65df0d58..57a3e9b38c0 100644 --- a/lib/config/config.pb.go +++ b/lib/config/config.pb.go @@ -972,10 +972,7 @@ func (m *Defaults) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthConfig - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthConfig } if (iNdEx + skippy) > l { diff --git a/lib/config/folderconfiguration.pb.go b/lib/config/folderconfiguration.pb.go index bcbc2a2409a..2989b8c4129 100644 --- a/lib/config/folderconfiguration.pb.go +++ b/lib/config/folderconfiguration.pb.go @@ -100,6 +100,7 @@ type FolderConfiguration struct { CopyRangeMethod fs.CopyRangeMethod `protobuf:"varint,32,opt,name=copy_range_method,json=copyRangeMethod,proto3,enum=fs.CopyRangeMethod" json:"copyRangeMethod" xml:"copyRangeMethod" default:"standard"` CaseSensitiveFS bool `protobuf:"varint,33,opt,name=case_sensitive_fs,json=caseSensitiveFs,proto3" json:"caseSensitiveFS" xml:"caseSensitiveFS"` JunctionsAsDirs bool `protobuf:"varint,34,opt,name=follow_junctions,json=followJunctions,proto3" json:"junctionsAsDirs" xml:"junctionsAsDirs"` + SyncOwnership bool `protobuf:"varint,35,opt,name=sync_ownership,json=syncOwnership,proto3" json:"syncOwnership" xml:"syncOwnership"` // Legacy deprecated DeprecatedReadOnly bool `protobuf:"varint,9000,opt,name=read_only,json=readOnly,proto3" json:"-" xml:"ro,attr,omitempty"` // Deprecated: Do not use. DeprecatedMinDiskFreePct float64 `protobuf:"fixed64,9001,opt,name=min_disk_free_pct,json=minDiskFreePct,proto3" json:"-" xml:"minDiskFreePct,omitempty"` // Deprecated: Do not use. @@ -149,135 +150,137 @@ func init() { } var fileDescriptor_44a9785876ed3afa = []byte{ - // 2043 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcd, 0x6f, 0x24, 0x47, - 0x15, 0x77, 0x7b, 0xbf, 0xec, 0xf2, 0x77, 0x79, 0xbd, 0xdb, 0xf1, 0x26, 0x53, 0x93, 0x66, 0x36, - 0x38, 0x51, 0xe2, 0xdd, 0x75, 0x10, 0x12, 0x2b, 0x16, 0xc8, 0xd8, 0xb1, 0x58, 0x16, 0x67, 0x47, - 0xed, 0x85, 0x15, 0x01, 0xa9, 0xe9, 0xe9, 0xae, 0x99, 0xa9, 0xb8, 0xbf, 0xa8, 0xea, 0x59, 0x7b, - 0xf6, 0x10, 0x2d, 0x17, 0x04, 0x22, 0x07, 0x64, 0x0e, 0xdc, 0x50, 0x24, 0x10, 0x82, 0xfc, 0x03, - 0x48, 0xfc, 0x05, 0x7b, 0x41, 0x9e, 0x13, 0x42, 0x1c, 0x4a, 0x8a, 0xf7, 0x36, 0xc7, 0x3e, 0xfa, - 0x84, 0xaa, 0xaa, 0xbb, 0xa7, 0xbb, 0x67, 0x22, 0x21, 0x71, 0x9b, 0xfa, 0xfd, 0x5e, 0xbd, 0xf7, - 0xeb, 0x57, 0xaf, 0x5e, 0xbf, 0x1e, 0xd0, 0xf0, 0x48, 0xfb, 0x8e, 0x13, 0x06, 0x1d, 0xd2, 0xbd, - 0xd3, 0x09, 0x3d, 0x17, 0x53, 0xb5, 0xe8, 0x53, 0x3b, 0x26, 0x61, 0xb0, 0x1d, 0xd1, 0x30, 0x0e, - 0xe1, 0x55, 0x05, 0x6e, 0xde, 0x9a, 0xb0, 0x8e, 0x07, 0x11, 0x56, 0x46, 0x9b, 0x1b, 0x05, 0x92, - 0x91, 0xe7, 0x19, 0xbc, 0x59, 0x80, 0xa3, 0xbe, 0xe7, 0x85, 0xd4, 0xc5, 0x34, 0xe5, 0xb6, 0x0a, - 0xdc, 0x33, 0x4c, 0x19, 0x09, 0x03, 0x12, 0x74, 0xa7, 0x28, 0xd8, 0x44, 0x05, 0xcb, 0xb6, 0x17, - 0x3a, 0x47, 0x55, 0x57, 0x50, 0x18, 0x74, 0xd8, 0x1d, 0x21, 0x88, 0xa5, 0xd8, 0xeb, 0x29, 0xe6, - 0x84, 0xd1, 0x80, 0xda, 0x41, 0x17, 0xfb, 0x38, 0xee, 0x85, 0x6e, 0xca, 0xce, 0xe3, 0x93, 0x58, - 0xfd, 0x34, 0xfe, 0x75, 0x09, 0xbc, 0xb6, 0x2f, 0x9f, 0x67, 0x0f, 0x3f, 0x23, 0x0e, 0xde, 0x2d, - 0x2a, 0x80, 0x5f, 0x68, 0x60, 0xde, 0x95, 0xb8, 0x45, 0x5c, 0x5d, 0xab, 0x6b, 0x5b, 0x8b, 0xcd, - 0xcf, 0xb4, 0x97, 0x1c, 0xcd, 0xfc, 0x87, 0xa3, 0x6f, 0x74, 0x49, 0xdc, 0xeb, 0xb7, 0xb7, 0x9d, - 0xd0, 0xbf, 0xc3, 0x06, 0x81, 0x13, 0xf7, 0x48, 0xd0, 0x2d, 0xfc, 0x12, 0x12, 0x64, 0x10, 0x27, - 0xf4, 0xb6, 0x95, 0xf7, 0x87, 0x7b, 0xe7, 0x1c, 0xcd, 0x65, 0xbf, 0x47, 0x1c, 0xcd, 0xb9, 0xe9, - 0xef, 0x84, 0xa3, 0xa5, 0x13, 0xdf, 0xbb, 0x6f, 0x10, 0xf7, 0x5d, 0x3b, 0x8e, 0xa9, 0x31, 0x3a, - 0x6b, 0x5c, 0x4b, 0x7f, 0x27, 0x67, 0x8d, 0xdc, 0xee, 0xd7, 0xc3, 0x86, 0x76, 0x3a, 0x6c, 0xe4, - 0x3e, 0xcc, 0x8c, 0x71, 0xe1, 0x5f, 0x34, 0xb0, 0x44, 0x82, 0x98, 0x86, 0x6e, 0xdf, 0xc1, 0xae, - 0xd5, 0x1e, 0xe8, 0xb3, 0x52, 0xf0, 0x8b, 0xff, 0x4b, 0xf0, 0x88, 0xa3, 0xc5, 0xb1, 0xd7, 0xe6, - 0x20, 0xe1, 0xe8, 0xa6, 0x12, 0x5a, 0x00, 0x73, 0xc9, 0x6b, 0x13, 0xa8, 0x10, 0x6c, 0x96, 0x3c, - 0x40, 0x07, 0xac, 0xe3, 0xc0, 0xa1, 0x83, 0x48, 0xe4, 0xd8, 0x8a, 0x6c, 0xc6, 0x8e, 0x43, 0xea, - 0xea, 0x97, 0xea, 0xda, 0xd6, 0x7c, 0x73, 0x67, 0xc4, 0x11, 0x1c, 0xd3, 0xad, 0x94, 0x4d, 0x38, - 0xd2, 0x65, 0xd8, 0x49, 0xca, 0x30, 0xa7, 0xd8, 0x1b, 0x7f, 0xac, 0x83, 0x75, 0x75, 0xb0, 0xe5, - 0x23, 0x3d, 0x04, 0xb3, 0xe9, 0x51, 0xce, 0x37, 0x77, 0xcf, 0x39, 0x9a, 0x95, 0x8f, 0x38, 0x4b, - 0x44, 0x84, 0x5a, 0xe9, 0x04, 0xea, 0x41, 0xe8, 0xe2, 0x8e, 0xdd, 0xf7, 0xe2, 0xfb, 0x46, 0x4c, - 0xfb, 0xb8, 0x78, 0x24, 0xa7, 0xc3, 0xc6, 0xec, 0xc3, 0xbd, 0xcf, 0xc5, 0xb3, 0xcd, 0x12, 0x17, - 0xfe, 0x08, 0x5c, 0xf1, 0xec, 0x36, 0xf6, 0x64, 0xc6, 0xe7, 0x9b, 0xdf, 0x1d, 0x71, 0xa4, 0x80, - 0x84, 0xa3, 0xba, 0x74, 0x2a, 0x57, 0xa9, 0x5f, 0x8a, 0x59, 0x6c, 0xd3, 0xf8, 0xbe, 0xd1, 0xb1, - 0x3d, 0x26, 0xdd, 0x82, 0x31, 0xfd, 0x62, 0xd8, 0x98, 0x31, 0xd5, 0x66, 0xd8, 0x05, 0x2b, 0x1d, - 0xe2, 0x61, 0x36, 0x60, 0x31, 0xf6, 0x2d, 0x51, 0xdf, 0x32, 0x49, 0xcb, 0x3b, 0x70, 0xbb, 0xc3, - 0xb6, 0xf7, 0x73, 0xea, 0xc9, 0x20, 0xc2, 0xcd, 0x77, 0x46, 0x1c, 0x2d, 0x77, 0x4a, 0x58, 0xc2, - 0xd1, 0x75, 0x19, 0xbd, 0x0c, 0x1b, 0x66, 0xc5, 0x0e, 0x1e, 0x80, 0xcb, 0x91, 0x1d, 0xf7, 0xf4, - 0xcb, 0x52, 0xfe, 0xb7, 0x46, 0x1c, 0xc9, 0x75, 0xc2, 0xd1, 0x2d, 0xb9, 0x5f, 0x2c, 0x52, 0xf1, - 0x79, 0x4a, 0x3e, 0x15, 0xc2, 0xe7, 0x73, 0xe6, 0xe2, 0xac, 0xa1, 0x7d, 0x6a, 0xca, 0x6d, 0xb0, - 0x05, 0x2e, 0x4b, 0xb1, 0x57, 0x52, 0xb1, 0xea, 0xf6, 0x6e, 0xab, 0xe3, 0x90, 0x62, 0xb7, 0x44, - 0x88, 0x58, 0x49, 0x5c, 0x91, 0x21, 0xc4, 0x22, 0x2f, 0xa3, 0xf9, 0x7c, 0x65, 0x4a, 0x2b, 0xf8, - 0x33, 0x70, 0x4d, 0xd5, 0x39, 0xd3, 0xaf, 0xd6, 0x2f, 0x6d, 0x2d, 0xec, 0xbc, 0x59, 0x76, 0x3a, - 0xe5, 0xf2, 0x36, 0x91, 0x28, 0xfb, 0x11, 0x47, 0xd9, 0xce, 0x84, 0xa3, 0x45, 0x19, 0x4a, 0xad, - 0x0d, 0x33, 0x23, 0xe0, 0xef, 0x35, 0xb0, 0x46, 0x31, 0x73, 0xec, 0xc0, 0x22, 0x41, 0x8c, 0xe9, - 0x33, 0xdb, 0xb3, 0x98, 0x7e, 0xad, 0xae, 0x6d, 0x5d, 0x69, 0x76, 0x47, 0x1c, 0xad, 0x28, 0xf2, - 0x61, 0xca, 0x1d, 0x26, 0x1c, 0xbd, 0x2d, 0x3d, 0x55, 0xf0, 0x6a, 0x8a, 0xde, 0xff, 0xe6, 0xdd, - 0xbb, 0xc6, 0x05, 0x47, 0x97, 0x48, 0x10, 0x8f, 0xce, 0x1a, 0xd7, 0xa7, 0x99, 0x5f, 0x9c, 0x35, - 0x2e, 0x0b, 0x3b, 0xb3, 0x1a, 0x04, 0xfe, 0x43, 0x03, 0xb0, 0xc3, 0xac, 0x63, 0x3b, 0x76, 0x7a, - 0x98, 0x5a, 0x38, 0xb0, 0xdb, 0x1e, 0x76, 0xf5, 0xb9, 0xba, 0xb6, 0x35, 0xd7, 0xfc, 0xad, 0x76, - 0xce, 0xd1, 0xea, 0xfe, 0xe1, 0x53, 0xc5, 0x7e, 0xa8, 0xc8, 0x11, 0x47, 0xab, 0x1d, 0x56, 0xc6, - 0x12, 0x8e, 0xde, 0x51, 0x45, 0x50, 0x21, 0xaa, 0x6a, 0xb3, 0x1a, 0xdf, 0x98, 0x6a, 0x28, 0x74, - 0x0a, 0x8b, 0xd3, 0x61, 0x63, 0x22, 0xac, 0x39, 0x11, 0x14, 0xfe, 0xbd, 0x2c, 0xde, 0xc5, 0x9e, - 0x3d, 0xb0, 0x98, 0x3e, 0x2f, 0x73, 0xfa, 0x1b, 0x21, 0x7e, 0x25, 0xf7, 0xb2, 0x27, 0xc8, 0x43, - 0x91, 0xe7, 0xdc, 0x8d, 0x82, 0x12, 0x8e, 0xbe, 0x5e, 0x96, 0xae, 0xf0, 0xaa, 0xf2, 0x7b, 0xa5, - 0x2c, 0x4f, 0x33, 0xbe, 0x38, 0x6b, 0xcc, 0xde, 0xbb, 0x7b, 0x3a, 0x6c, 0x54, 0xa3, 0x9a, 0xd5, - 0x98, 0xf0, 0xe7, 0x60, 0x91, 0x74, 0x83, 0x90, 0x62, 0x2b, 0xc2, 0xd4, 0x67, 0x3a, 0x90, 0xf9, - 0x7e, 0x30, 0xe2, 0x68, 0x41, 0xe1, 0x2d, 0x01, 0x27, 0x1c, 0xdd, 0x50, 0xdd, 0x62, 0x8c, 0xe5, - 0xe5, 0xbb, 0x5a, 0x05, 0xcd, 0xe2, 0x56, 0xf8, 0x4b, 0x0d, 0x2c, 0xdb, 0xfd, 0x38, 0xb4, 0x82, - 0x90, 0xfa, 0xb6, 0x47, 0x9e, 0x63, 0x7d, 0x41, 0x06, 0xf9, 0x78, 0xc4, 0xd1, 0x92, 0x60, 0x3e, - 0xca, 0x88, 0x3c, 0x03, 0x25, 0xf4, 0xab, 0x4e, 0x0e, 0x4e, 0x5a, 0x65, 0xc7, 0x66, 0x96, 0xfd, - 0xc2, 0x10, 0x2c, 0xf9, 0x24, 0xb0, 0x5c, 0xc2, 0x8e, 0xac, 0x0e, 0xc5, 0x58, 0x5f, 0xac, 0x6b, - 0x5b, 0x0b, 0x3b, 0x8b, 0xd9, 0xb5, 0x3a, 0x24, 0xcf, 0x71, 0xf3, 0x41, 0x7a, 0x83, 0x16, 0x7c, - 0x12, 0xec, 0x11, 0x76, 0xb4, 0x4f, 0xb1, 0x50, 0x84, 0xa4, 0xa2, 0x02, 0x56, 0x3c, 0x8a, 0xfa, - 0x6d, 0xe3, 0xe2, 0xac, 0x71, 0xe9, 0x5e, 0xfd, 0xb6, 0x59, 0xdc, 0x06, 0xbb, 0x00, 0x8c, 0xdf, - 0xf3, 0xfa, 0x92, 0x8c, 0x86, 0xb2, 0x68, 0x3f, 0xce, 0x99, 0xf2, 0x15, 0x7e, 0x2b, 0x15, 0x50, - 0xd8, 0x9a, 0x70, 0xb4, 0x2a, 0xe3, 0x8f, 0x21, 0xc3, 0x2c, 0xf0, 0xf0, 0x01, 0xb8, 0xe6, 0x84, - 0x11, 0xc1, 0x94, 0xe9, 0xcb, 0xb2, 0xda, 0xbe, 0x26, 0x7a, 0x40, 0x0a, 0xe5, 0xaf, 0xd9, 0x74, - 0x9d, 0xd5, 0x8d, 0x99, 0x19, 0xc0, 0x7f, 0x6a, 0xe0, 0x86, 0x98, 0x30, 0x30, 0xb5, 0x7c, 0xfb, - 0xc4, 0x8a, 0x70, 0xe0, 0x92, 0xa0, 0x6b, 0x1d, 0x91, 0xb6, 0xbe, 0x22, 0xdd, 0xfd, 0x41, 0x14, - 0xef, 0x7a, 0x4b, 0x9a, 0x1c, 0xd8, 0x27, 0x2d, 0x65, 0xf0, 0x88, 0x34, 0x47, 0x1c, 0xad, 0x47, - 0x93, 0x70, 0xc2, 0xd1, 0x6b, 0xaa, 0x89, 0x4e, 0x72, 0x85, 0xb2, 0x9d, 0xba, 0x75, 0x3a, 0x7c, - 0x3a, 0x6c, 0x4c, 0x8b, 0x6f, 0x4e, 0xb1, 0x6d, 0x8b, 0x74, 0xf4, 0x6c, 0xd6, 0x13, 0xe9, 0x58, - 0x1d, 0xa7, 0x23, 0x85, 0xf2, 0x74, 0xa4, 0xeb, 0x71, 0x3a, 0x52, 0x00, 0x7e, 0x00, 0xae, 0xc8, - 0x59, 0x4b, 0x5f, 0x93, 0xbd, 0x7c, 0x2d, 0x3b, 0x31, 0x11, 0xff, 0xb1, 0x20, 0x9a, 0xba, 0x78, - 0xd9, 0x49, 0x9b, 0x84, 0xa3, 0x05, 0xe9, 0x4d, 0xae, 0x0c, 0x53, 0xa1, 0xf0, 0x11, 0x58, 0x4a, - 0x2f, 0x94, 0x8b, 0x3d, 0x1c, 0x63, 0x1d, 0xca, 0x62, 0x7f, 0x4b, 0x4e, 0x16, 0x92, 0xd8, 0x93, - 0x78, 0xc2, 0x11, 0x2c, 0x5c, 0x29, 0x05, 0x1a, 0x66, 0xc9, 0x06, 0x9e, 0x00, 0x5d, 0xf6, 0xe9, - 0x88, 0x86, 0x5d, 0x8a, 0x19, 0x2b, 0x36, 0xec, 0x75, 0xf9, 0x7c, 0xe2, 0xe5, 0xbb, 0x21, 0x6c, - 0x5a, 0xa9, 0x49, 0xb1, 0x6d, 0xab, 0xd7, 0xd9, 0x54, 0x36, 0x7f, 0xf6, 0xe9, 0x9b, 0xe1, 0x21, - 0x58, 0x4e, 0xeb, 0x22, 0xb2, 0xfb, 0x0c, 0x5b, 0x4c, 0xbf, 0x2e, 0xe3, 0xbd, 0x27, 0x9e, 0x43, - 0x31, 0x2d, 0x41, 0x1c, 0xe6, 0xcf, 0x51, 0x04, 0x73, 0xef, 0x25, 0x53, 0x88, 0xc1, 0x92, 0xa8, - 0x32, 0x91, 0x54, 0x8f, 0x38, 0x31, 0xd3, 0x37, 0xa4, 0xcf, 0xef, 0x09, 0x9f, 0xbe, 0x7d, 0xb2, - 0x9b, 0xe1, 0xe3, 0x5b, 0x57, 0x00, 0xa7, 0x76, 0x40, 0xd5, 0xe9, 0xcc, 0xd2, 0x6e, 0xe8, 0x82, - 0xeb, 0x2e, 0x61, 0xa2, 0x33, 0x5b, 0x2c, 0xb2, 0x29, 0xc3, 0x96, 0x1c, 0x00, 0xf4, 0x1b, 0xf2, - 0x24, 0xe4, 0xc8, 0x95, 0xf2, 0x87, 0x92, 0x96, 0xa3, 0x45, 0x3e, 0x72, 0x4d, 0x52, 0x86, 0x39, - 0xc5, 0xbe, 0x18, 0x25, 0xc6, 0x7e, 0x64, 0x91, 0xc0, 0xc5, 0x27, 0x98, 0xe9, 0x37, 0x27, 0xa2, - 0x3c, 0xc1, 0x7e, 0xf4, 0x50, 0xb1, 0xd5, 0x28, 0x05, 0x6a, 0x1c, 0xa5, 0x00, 0xc2, 0x1d, 0x70, - 0x55, 0x1e, 0x80, 0xab, 0xeb, 0xd2, 0xef, 0xe6, 0x88, 0xa3, 0x14, 0xc9, 0xdf, 0xf0, 0x6a, 0x69, - 0x98, 0x29, 0x0e, 0x63, 0x70, 0xf3, 0x18, 0xdb, 0x47, 0x96, 0xa8, 0x6a, 0x2b, 0xee, 0x51, 0xcc, - 0x7a, 0xa1, 0xe7, 0x5a, 0x91, 0x13, 0xeb, 0xaf, 0xc9, 0x84, 0x8b, 0xf6, 0x7e, 0x5d, 0x98, 0x7c, - 0xdf, 0x66, 0xbd, 0x27, 0x99, 0x41, 0xcb, 0x89, 0x13, 0x8e, 0x36, 0xa5, 0xcb, 0x69, 0x64, 0x7e, - 0xa8, 0x53, 0xb7, 0xc2, 0x5d, 0xb0, 0xe0, 0xdb, 0xf4, 0x08, 0x53, 0x2b, 0xb0, 0x7d, 0xac, 0x6f, - 0xca, 0xe1, 0xca, 0x10, 0xed, 0x4c, 0xc1, 0x1f, 0xd9, 0x3e, 0xce, 0xdb, 0xd9, 0x18, 0x32, 0xcc, - 0x02, 0x0f, 0x07, 0x60, 0x53, 0x7c, 0xc4, 0x58, 0xe1, 0x71, 0x80, 0x29, 0xeb, 0x91, 0xc8, 0xea, - 0xd0, 0xd0, 0xb7, 0x22, 0x9b, 0xe2, 0x20, 0xd6, 0x6f, 0xc9, 0x14, 0x7c, 0x7b, 0xc4, 0xd1, 0x4d, - 0x61, 0xf5, 0x38, 0x33, 0xda, 0xa7, 0xa1, 0xdf, 0x92, 0x26, 0x09, 0x47, 0x6f, 0x64, 0x1d, 0x6f, - 0x1a, 0x6f, 0x98, 0x5f, 0xb5, 0x13, 0xfe, 0x4a, 0x03, 0x6b, 0x7e, 0xe8, 0x5a, 0x31, 0xf1, 0xb1, - 0x75, 0x4c, 0x02, 0x37, 0x3c, 0xb6, 0x98, 0xfe, 0xba, 0x4c, 0xd8, 0x4f, 0xcf, 0x39, 0x5a, 0x33, - 0xed, 0xe3, 0x83, 0xd0, 0x7d, 0x42, 0x7c, 0xfc, 0x54, 0xb2, 0xe2, 0x1d, 0xbe, 0xec, 0x97, 0x90, - 0x7c, 0x04, 0x2d, 0xc3, 0x59, 0xe6, 0x4e, 0x87, 0x8d, 0x49, 0x2f, 0x66, 0xc5, 0x07, 0x7c, 0xa1, - 0x81, 0x8d, 0xf4, 0x9a, 0x38, 0x7d, 0x2a, 0xb4, 0x59, 0xc7, 0x94, 0xc4, 0x98, 0xe9, 0x6f, 0x48, - 0x31, 0x3f, 0x14, 0xad, 0x57, 0x15, 0x7c, 0xca, 0x3f, 0x95, 0x74, 0xc2, 0xd1, 0xed, 0xc2, 0xad, - 0x29, 0x71, 0x85, 0xcb, 0xb3, 0x53, 0xb8, 0x3b, 0xda, 0x8e, 0x39, 0xcd, 0x93, 0x68, 0x62, 0x59, - 0x6d, 0x77, 0xc4, 0x17, 0x93, 0x5e, 0x1b, 0x37, 0xb1, 0x94, 0xd8, 0x17, 0x78, 0x7e, 0xf9, 0x8b, - 0xa0, 0x61, 0x96, 0x6c, 0xa0, 0x07, 0x56, 0xe5, 0x97, 0xac, 0x25, 0x7a, 0x81, 0xa5, 0xfa, 0x2b, - 0x92, 0xfd, 0xf5, 0x46, 0xd6, 0x5f, 0x9b, 0x82, 0x1f, 0x37, 0x59, 0x39, 0xdc, 0xb7, 0x4b, 0x58, - 0x9e, 0xd9, 0x32, 0x6c, 0x98, 0x15, 0x3b, 0xf8, 0x99, 0x06, 0xd6, 0x64, 0x09, 0xc9, 0x0f, 0x61, - 0x4b, 0x7d, 0x09, 0xeb, 0x75, 0x19, 0x6f, 0x5d, 0x7c, 0x48, 0xec, 0x86, 0xd1, 0xc0, 0x14, 0xdc, - 0x81, 0xa4, 0x9a, 0x8f, 0xc4, 0x28, 0xe6, 0x94, 0xc1, 0x84, 0xa3, 0xad, 0xbc, 0x8c, 0x0a, 0x78, - 0x21, 0x8d, 0x2c, 0xb6, 0x03, 0xd7, 0xa6, 0xae, 0x78, 0xff, 0xcf, 0x65, 0x0b, 0xb3, 0xea, 0x08, - 0xfe, 0x59, 0xc8, 0xb1, 0x45, 0x03, 0xc5, 0x01, 0x23, 0x31, 0x79, 0x26, 0x32, 0xaa, 0xbf, 0x29, - 0xd3, 0x79, 0x22, 0xe6, 0xc2, 0x5d, 0x9b, 0xe1, 0xc3, 0x8c, 0xdb, 0x97, 0x73, 0xa1, 0x53, 0x86, - 0x12, 0x8e, 0x36, 0x94, 0x98, 0x32, 0x2e, 0x66, 0xa0, 0x09, 0xdb, 0x49, 0x48, 0x8c, 0x81, 0x95, - 0x20, 0x66, 0xc5, 0x86, 0xc1, 0x3f, 0x69, 0x60, 0xb5, 0x13, 0x7a, 0x5e, 0x78, 0x6c, 0x7d, 0xd2, - 0x0f, 0x1c, 0x31, 0x8e, 0x30, 0xdd, 0x18, 0xab, 0xfc, 0x41, 0x06, 0x7e, 0xc0, 0xf6, 0x08, 0x65, - 0x42, 0xe5, 0x27, 0x65, 0x28, 0x57, 0x59, 0xc1, 0xa5, 0xca, 0xaa, 0xed, 0x24, 0x24, 0x54, 0x56, - 0x82, 0x98, 0x2b, 0x4a, 0x51, 0x0e, 0xc3, 0x23, 0x30, 0x4f, 0xb1, 0xed, 0x5a, 0x61, 0xe0, 0x0d, - 0xf4, 0xbf, 0xee, 0x4b, 0x79, 0x07, 0xe7, 0x1c, 0xc1, 0x3d, 0x1c, 0x51, 0xec, 0xd8, 0x31, 0x76, - 0x4d, 0x6c, 0xbb, 0x8f, 0x03, 0x6f, 0x30, 0xe2, 0x48, 0x7b, 0x2f, 0xff, 0x7a, 0xa7, 0xa1, 0x1c, - 0x0f, 0xdf, 0x0d, 0x7d, 0x22, 0x7a, 0x75, 0x3c, 0x90, 0x5f, 0xef, 0x13, 0xa8, 0xae, 0x99, 0x73, - 0x34, 0x75, 0x00, 0x7f, 0x01, 0xd6, 0x4a, 0x33, 0xa3, 0xec, 0x9f, 0x7f, 0x13, 0x41, 0xb5, 0xe6, - 0x87, 0xe7, 0x1c, 0xe9, 0xe3, 0xa0, 0x07, 0xe3, 0xc9, 0xaf, 0xe5, 0xc4, 0x59, 0xe8, 0x5a, 0x75, - 0x70, 0x6c, 0x39, 0x71, 0x41, 0x81, 0xae, 0x99, 0xcb, 0x65, 0x12, 0xfe, 0x04, 0x5c, 0x53, 0xef, - 0x4b, 0xa6, 0x7f, 0xb1, 0x2f, 0xef, 0xfa, 0x77, 0x44, 0xe3, 0x19, 0x07, 0x52, 0x73, 0x10, 0x2b, - 0x3f, 0x5c, 0xba, 0xa5, 0xe0, 0x3a, 0xbd, 0xe0, 0xba, 0x66, 0x66, 0xfe, 0x9a, 0x8f, 0x5e, 0x7e, - 0x59, 0x9b, 0x19, 0x7e, 0x59, 0x9b, 0x79, 0x79, 0x5e, 0xd3, 0x86, 0xe7, 0x35, 0xed, 0x77, 0xaf, - 0x6a, 0x33, 0x9f, 0xbf, 0xaa, 0x69, 0xc3, 0x57, 0xb5, 0x99, 0x7f, 0xbf, 0xaa, 0xcd, 0x7c, 0xfc, - 0xf6, 0xff, 0xf0, 0x7f, 0x89, 0xba, 0xae, 0xed, 0xab, 0xf2, 0x7f, 0x93, 0xf7, 0xff, 0x1b, 0x00, - 0x00, 0xff, 0xff, 0x3e, 0xb6, 0x85, 0xe6, 0x55, 0x13, 0x00, 0x00, + // 2074 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcd, 0x6f, 0xdc, 0xc6, + 0x15, 0x17, 0xe5, 0x2f, 0x69, 0xf4, 0x3d, 0xb2, 0xec, 0xb1, 0x9c, 0xec, 0x6c, 0x98, 0x75, 0xaa, + 0x04, 0x89, 0x6c, 0x2b, 0x45, 0x81, 0x1a, 0x75, 0xdb, 0xac, 0x14, 0xa1, 0xae, 0xab, 0x78, 0x41, + 0xb9, 0x35, 0x9a, 0x16, 0x60, 0xb9, 0xe4, 0xec, 0x2e, 0x23, 0x7e, 0x75, 0x86, 0x6b, 0x69, 0x7d, + 0x08, 0xdc, 0x4b, 0xd1, 0xa2, 0x39, 0x14, 0xea, 0xa1, 0xd7, 0x00, 0x2d, 0x8a, 0x36, 0xff, 0x40, + 0x81, 0xfe, 0x05, 0xbe, 0x14, 0xda, 0x53, 0x51, 0xf4, 0x30, 0x40, 0xe4, 0xdb, 0x5e, 0x0a, 0xf0, + 0xe8, 0x53, 0x31, 0x33, 0x24, 0x97, 0xe4, 0x6e, 0x80, 0x02, 0xb9, 0xed, 0xfc, 0x7e, 0x6f, 0xde, + 0xfb, 0xf1, 0xcd, 0x9b, 0xc7, 0xc7, 0x05, 0x0d, 0xcf, 0x6d, 0xdf, 0xb6, 0xc3, 0xa0, 0xe3, 0x76, + 0x6f, 0x77, 0x42, 0xcf, 0x21, 0x54, 0x2d, 0xfa, 0xd4, 0x8a, 0xdd, 0x30, 0xd8, 0x8e, 0x68, 0x18, + 0x87, 0xf0, 0xb2, 0x02, 0x37, 0x6f, 0x4e, 0x58, 0xc7, 0x83, 0x88, 0x28, 0xa3, 0xcd, 0x8d, 0x02, + 0xc9, 0xdc, 0x67, 0x19, 0xbc, 0x59, 0x80, 0xa3, 0xbe, 0xe7, 0x85, 0xd4, 0x21, 0x34, 0xe5, 0xb6, + 0x0a, 0xdc, 0x53, 0x42, 0x99, 0x1b, 0x06, 0x6e, 0xd0, 0x9d, 0xa2, 0x60, 0x13, 0x17, 0x2c, 0xdb, + 0x5e, 0x68, 0x1f, 0x55, 0x5d, 0x41, 0x61, 0xd0, 0x61, 0xb7, 0x85, 0x20, 0x96, 0x62, 0xaf, 0xa5, + 0x98, 0x1d, 0x46, 0x03, 0x6a, 0x05, 0x5d, 0xe2, 0x93, 0xb8, 0x17, 0x3a, 0x29, 0x3b, 0x4f, 0x4e, + 0x62, 0xf5, 0x53, 0xff, 0xd7, 0x05, 0x70, 0x63, 0x5f, 0x3e, 0xcf, 0x1e, 0x79, 0xea, 0xda, 0x64, + 0xb7, 0xa8, 0x00, 0x7e, 0xa1, 0x81, 0x79, 0x47, 0xe2, 0xa6, 0xeb, 0x20, 0xad, 0xae, 0x6d, 0x2d, + 0x36, 0x3f, 0xd3, 0x5e, 0x70, 0x3c, 0xf3, 0x1f, 0x8e, 0xbf, 0xd9, 0x75, 0xe3, 0x5e, 0xbf, 0xbd, + 0x6d, 0x87, 0xfe, 0x6d, 0x36, 0x08, 0xec, 0xb8, 0xe7, 0x06, 0xdd, 0xc2, 0x2f, 0x21, 0x41, 0x06, + 0xb1, 0x43, 0x6f, 0x5b, 0x79, 0x7f, 0xb0, 0x77, 0xce, 0xf1, 0x5c, 0xf6, 0x7b, 0xc4, 0xf1, 0x9c, + 0x93, 0xfe, 0x4e, 0x38, 0x5e, 0x3a, 0xf1, 0xbd, 0x7b, 0xba, 0xeb, 0xbc, 0x6b, 0xc5, 0x31, 0xd5, + 0x47, 0x67, 0x8d, 0x2b, 0xe9, 0xef, 0xe4, 0xac, 0x91, 0xdb, 0xfd, 0x66, 0xd8, 0xd0, 0x4e, 0x87, + 0x8d, 0xdc, 0x87, 0x91, 0x31, 0x0e, 0xfc, 0x8b, 0x06, 0x96, 0xdc, 0x20, 0xa6, 0xa1, 0xd3, 0xb7, + 0x89, 0x63, 0xb6, 0x07, 0x68, 0x56, 0x0a, 0x7e, 0xfe, 0xb5, 0x04, 0x8f, 0x38, 0x5e, 0x1c, 0x7b, + 0x6d, 0x0e, 0x12, 0x8e, 0xaf, 0x2b, 0xa1, 0x05, 0x30, 0x97, 0xbc, 0x36, 0x81, 0x0a, 0xc1, 0x46, + 0xc9, 0x03, 0xb4, 0xc1, 0x3a, 0x09, 0x6c, 0x3a, 0x88, 0x44, 0x8e, 0xcd, 0xc8, 0x62, 0xec, 0x38, + 0xa4, 0x0e, 0xba, 0x50, 0xd7, 0xb6, 0xe6, 0x9b, 0x3b, 0x23, 0x8e, 0xe1, 0x98, 0x6e, 0xa5, 0x6c, + 0xc2, 0x31, 0x92, 0x61, 0x27, 0x29, 0xdd, 0x98, 0x62, 0xaf, 0xff, 0xb7, 0x0e, 0xd6, 0xd5, 0xc1, + 0x96, 0x8f, 0xf4, 0x10, 0xcc, 0xa6, 0x47, 0x39, 0xdf, 0xdc, 0x3d, 0xe7, 0x78, 0x56, 0x3e, 0xe2, + 0xac, 0x2b, 0x22, 0xd4, 0x4a, 0x27, 0x50, 0x0f, 0x42, 0x87, 0x74, 0xac, 0xbe, 0x17, 0xdf, 0xd3, + 0x63, 0xda, 0x27, 0xc5, 0x23, 0x39, 0x1d, 0x36, 0x66, 0x1f, 0xec, 0x7d, 0x2e, 0x9e, 0x6d, 0xd6, + 0x75, 0xe0, 0x8f, 0xc1, 0x25, 0xcf, 0x6a, 0x13, 0x4f, 0x66, 0x7c, 0xbe, 0xf9, 0xbd, 0x11, 0xc7, + 0x0a, 0x48, 0x38, 0xae, 0x4b, 0xa7, 0x72, 0x95, 0xfa, 0xa5, 0x84, 0xc5, 0x16, 0x8d, 0xef, 0xe9, + 0x1d, 0xcb, 0x63, 0xd2, 0x2d, 0x18, 0xd3, 0xcf, 0x87, 0x8d, 0x19, 0x43, 0x6d, 0x86, 0x5d, 0xb0, + 0xd2, 0x71, 0x3d, 0xc2, 0x06, 0x2c, 0x26, 0xbe, 0x29, 0xea, 0x5b, 0x26, 0x69, 0x79, 0x07, 0x6e, + 0x77, 0xd8, 0xf6, 0x7e, 0x4e, 0x3d, 0x1e, 0x44, 0xa4, 0xf9, 0xce, 0x88, 0xe3, 0xe5, 0x4e, 0x09, + 0x4b, 0x38, 0xbe, 0x2a, 0xa3, 0x97, 0x61, 0xdd, 0xa8, 0xd8, 0xc1, 0x03, 0x70, 0x31, 0xb2, 0xe2, + 0x1e, 0xba, 0x28, 0xe5, 0x7f, 0x7b, 0xc4, 0xb1, 0x5c, 0x27, 0x1c, 0xdf, 0x94, 0xfb, 0xc5, 0x22, + 0x15, 0x9f, 0xa7, 0xe4, 0x53, 0x21, 0x7c, 0x3e, 0x67, 0x5e, 0x9d, 0x35, 0xb4, 0x4f, 0x0d, 0xb9, + 0x0d, 0xb6, 0xc0, 0x45, 0x29, 0xf6, 0x52, 0x2a, 0x56, 0xdd, 0xde, 0x6d, 0x75, 0x1c, 0x52, 0xec, + 0x96, 0x08, 0x11, 0x2b, 0x89, 0x2b, 0x32, 0x84, 0x58, 0xe4, 0x65, 0x34, 0x9f, 0xaf, 0x0c, 0x69, + 0x05, 0x7f, 0x0e, 0xae, 0xa8, 0x3a, 0x67, 0xe8, 0x72, 0xfd, 0xc2, 0xd6, 0xc2, 0xce, 0x1b, 0x65, + 0xa7, 0x53, 0x2e, 0x6f, 0x13, 0x8b, 0xb2, 0x1f, 0x71, 0x9c, 0xed, 0x4c, 0x38, 0x5e, 0x94, 0xa1, + 0xd4, 0x5a, 0x37, 0x32, 0x02, 0xfe, 0x41, 0x03, 0x6b, 0x94, 0x30, 0xdb, 0x0a, 0x4c, 0x37, 0x88, + 0x09, 0x7d, 0x6a, 0x79, 0x26, 0x43, 0x57, 0xea, 0xda, 0xd6, 0xa5, 0x66, 0x77, 0xc4, 0xf1, 0x8a, + 0x22, 0x1f, 0xa4, 0xdc, 0x61, 0xc2, 0xf1, 0xdb, 0xd2, 0x53, 0x05, 0xaf, 0xa6, 0xe8, 0xfd, 0x6f, + 0xdd, 0xb9, 0xa3, 0xbf, 0xe2, 0xf8, 0x82, 0x1b, 0xc4, 0xa3, 0xb3, 0xc6, 0xd5, 0x69, 0xe6, 0xaf, + 0xce, 0x1a, 0x17, 0x85, 0x9d, 0x51, 0x0d, 0x02, 0xff, 0xa1, 0x01, 0xd8, 0x61, 0xe6, 0xb1, 0x15, + 0xdb, 0x3d, 0x42, 0x4d, 0x12, 0x58, 0x6d, 0x8f, 0x38, 0x68, 0xae, 0xae, 0x6d, 0xcd, 0x35, 0x7f, + 0xa7, 0x9d, 0x73, 0xbc, 0xba, 0x7f, 0xf8, 0x44, 0xb1, 0x1f, 0x2a, 0x72, 0xc4, 0xf1, 0x6a, 0x87, + 0x95, 0xb1, 0x84, 0xe3, 0x77, 0x54, 0x11, 0x54, 0x88, 0xaa, 0xda, 0xac, 0xc6, 0x37, 0xa6, 0x1a, + 0x0a, 0x9d, 0xc2, 0xe2, 0x74, 0xd8, 0x98, 0x08, 0x6b, 0x4c, 0x04, 0x85, 0x7f, 0x2f, 0x8b, 0x77, + 0x88, 0x67, 0x0d, 0x4c, 0x86, 0xe6, 0x65, 0x4e, 0x7f, 0x2b, 0xc4, 0xaf, 0xe4, 0x5e, 0xf6, 0x04, + 0x79, 0x28, 0xf2, 0x9c, 0xbb, 0x51, 0x50, 0xc2, 0xf1, 0x37, 0xca, 0xd2, 0x15, 0x5e, 0x55, 0x7e, + 0xb7, 0x94, 0xe5, 0x69, 0xc6, 0xaf, 0xce, 0x1a, 0xb3, 0x77, 0xef, 0x9c, 0x0e, 0x1b, 0xd5, 0xa8, + 0x46, 0x35, 0x26, 0xfc, 0x05, 0x58, 0x74, 0xbb, 0x41, 0x48, 0x89, 0x19, 0x11, 0xea, 0x33, 0x04, + 0x64, 0xbe, 0xef, 0x8f, 0x38, 0x5e, 0x50, 0x78, 0x4b, 0xc0, 0x09, 0xc7, 0xd7, 0x54, 0xb7, 0x18, + 0x63, 0x79, 0xf9, 0xae, 0x56, 0x41, 0xa3, 0xb8, 0x15, 0xfe, 0x4a, 0x03, 0xcb, 0x56, 0x3f, 0x0e, + 0xcd, 0x20, 0xa4, 0xbe, 0xe5, 0xb9, 0xcf, 0x08, 0x5a, 0x90, 0x41, 0x3e, 0x1e, 0x71, 0xbc, 0x24, + 0x98, 0x8f, 0x32, 0x22, 0xcf, 0x40, 0x09, 0xfd, 0xaa, 0x93, 0x83, 0x93, 0x56, 0xd9, 0xb1, 0x19, + 0x65, 0xbf, 0x30, 0x04, 0x4b, 0xbe, 0x1b, 0x98, 0x8e, 0xcb, 0x8e, 0xcc, 0x0e, 0x25, 0x04, 0x2d, + 0xd6, 0xb5, 0xad, 0x85, 0x9d, 0xc5, 0xec, 0x5a, 0x1d, 0xba, 0xcf, 0x48, 0xf3, 0x7e, 0x7a, 0x83, + 0x16, 0x7c, 0x37, 0xd8, 0x73, 0xd9, 0xd1, 0x3e, 0x25, 0x42, 0x11, 0x96, 0x8a, 0x0a, 0x58, 0xf1, + 0x28, 0xea, 0xb7, 0xf4, 0x57, 0x67, 0x8d, 0x0b, 0x77, 0xeb, 0xb7, 0x8c, 0xe2, 0x36, 0xd8, 0x05, + 0x60, 0xfc, 0x9e, 0x47, 0x4b, 0x32, 0x1a, 0xce, 0xa2, 0xfd, 0x24, 0x67, 0xca, 0x57, 0xf8, 0xad, + 0x54, 0x40, 0x61, 0x6b, 0xc2, 0xf1, 0xaa, 0x8c, 0x3f, 0x86, 0x74, 0xa3, 0xc0, 0xc3, 0xfb, 0xe0, + 0x8a, 0x1d, 0x46, 0x2e, 0xa1, 0x0c, 0x2d, 0xcb, 0x6a, 0x7b, 0x53, 0xf4, 0x80, 0x14, 0xca, 0x5f, + 0xb3, 0xe9, 0x3a, 0xab, 0x1b, 0x23, 0x33, 0x80, 0xff, 0xd4, 0xc0, 0x35, 0x31, 0x61, 0x10, 0x6a, + 0xfa, 0xd6, 0x89, 0x19, 0x91, 0xc0, 0x71, 0x83, 0xae, 0x79, 0xe4, 0xb6, 0xd1, 0x8a, 0x74, 0xf7, + 0x47, 0x51, 0xbc, 0xeb, 0x2d, 0x69, 0x72, 0x60, 0x9d, 0xb4, 0x94, 0xc1, 0x43, 0xb7, 0x39, 0xe2, + 0x78, 0x3d, 0x9a, 0x84, 0x13, 0x8e, 0x6f, 0xa8, 0x26, 0x3a, 0xc9, 0x15, 0xca, 0x76, 0xea, 0xd6, + 0xe9, 0xf0, 0xe9, 0xb0, 0x31, 0x2d, 0xbe, 0x31, 0xc5, 0xb6, 0x2d, 0xd2, 0xd1, 0xb3, 0x58, 0x4f, + 0xa4, 0x63, 0x75, 0x9c, 0x8e, 0x14, 0xca, 0xd3, 0x91, 0xae, 0xc7, 0xe9, 0x48, 0x01, 0xf8, 0x01, + 0xb8, 0x24, 0x67, 0x2d, 0xb4, 0x26, 0x7b, 0xf9, 0x5a, 0x76, 0x62, 0x22, 0xfe, 0x23, 0x41, 0x34, + 0x91, 0x78, 0xd9, 0x49, 0x9b, 0x84, 0xe3, 0x05, 0xe9, 0x4d, 0xae, 0x74, 0x43, 0xa1, 0xf0, 0x21, + 0x58, 0x4a, 0x2f, 0x94, 0x43, 0x3c, 0x12, 0x13, 0x04, 0x65, 0xb1, 0xbf, 0x25, 0x27, 0x0b, 0x49, + 0xec, 0x49, 0x3c, 0xe1, 0x18, 0x16, 0xae, 0x94, 0x02, 0x75, 0xa3, 0x64, 0x03, 0x4f, 0x00, 0x92, + 0x7d, 0x3a, 0xa2, 0x61, 0x97, 0x12, 0xc6, 0x8a, 0x0d, 0x7b, 0x5d, 0x3e, 0x9f, 0x78, 0xf9, 0x6e, + 0x08, 0x9b, 0x56, 0x6a, 0x52, 0x6c, 0xdb, 0xea, 0x75, 0x36, 0x95, 0xcd, 0x9f, 0x7d, 0xfa, 0x66, + 0x78, 0x08, 0x96, 0xd3, 0xba, 0x88, 0xac, 0x3e, 0x23, 0x26, 0x43, 0x57, 0x65, 0xbc, 0xf7, 0xc4, + 0x73, 0x28, 0xa6, 0x25, 0x88, 0xc3, 0xfc, 0x39, 0x8a, 0x60, 0xee, 0xbd, 0x64, 0x0a, 0x09, 0x58, + 0x12, 0x55, 0x26, 0x92, 0xea, 0xb9, 0x76, 0xcc, 0xd0, 0x86, 0xf4, 0xf9, 0x7d, 0xe1, 0xd3, 0xb7, + 0x4e, 0x76, 0x33, 0x7c, 0x7c, 0xeb, 0x0a, 0xe0, 0xd4, 0x0e, 0xa8, 0x3a, 0x9d, 0x51, 0xda, 0x0d, + 0x1d, 0x70, 0xd5, 0x71, 0x99, 0xe8, 0xcc, 0x26, 0x8b, 0x2c, 0xca, 0x88, 0x29, 0x07, 0x00, 0x74, + 0x4d, 0x9e, 0x84, 0x1c, 0xb9, 0x52, 0xfe, 0x50, 0xd2, 0x72, 0xb4, 0xc8, 0x47, 0xae, 0x49, 0x4a, + 0x37, 0xa6, 0xd8, 0x17, 0xa3, 0xc4, 0xc4, 0x8f, 0x4c, 0x37, 0x70, 0xc8, 0x09, 0x61, 0xe8, 0xfa, + 0x44, 0x94, 0xc7, 0xc4, 0x8f, 0x1e, 0x28, 0xb6, 0x1a, 0xa5, 0x40, 0x8d, 0xa3, 0x14, 0x40, 0xb8, + 0x03, 0x2e, 0xcb, 0x03, 0x70, 0x10, 0x92, 0x7e, 0x37, 0x47, 0x1c, 0xa7, 0x48, 0xfe, 0x86, 0x57, + 0x4b, 0xdd, 0x48, 0x71, 0x18, 0x83, 0xeb, 0xc7, 0xc4, 0x3a, 0x32, 0x45, 0x55, 0x9b, 0x71, 0x8f, + 0x12, 0xd6, 0x0b, 0x3d, 0xc7, 0x8c, 0xec, 0x18, 0xdd, 0x90, 0x09, 0x17, 0xed, 0xfd, 0xaa, 0x30, + 0xf9, 0x81, 0xc5, 0x7a, 0x8f, 0x33, 0x83, 0x96, 0x1d, 0x27, 0x1c, 0x6f, 0x4a, 0x97, 0xd3, 0xc8, + 0xfc, 0x50, 0xa7, 0x6e, 0x85, 0xbb, 0x60, 0xc1, 0xb7, 0xe8, 0x11, 0xa1, 0x66, 0x60, 0xf9, 0x04, + 0x6d, 0xca, 0xe1, 0x4a, 0x17, 0xed, 0x4c, 0xc1, 0x1f, 0x59, 0x3e, 0xc9, 0xdb, 0xd9, 0x18, 0xd2, + 0x8d, 0x02, 0x0f, 0x07, 0x60, 0x53, 0x7c, 0xc4, 0x98, 0xe1, 0x71, 0x40, 0x28, 0xeb, 0xb9, 0x91, + 0xd9, 0xa1, 0xa1, 0x6f, 0x46, 0x16, 0x25, 0x41, 0x8c, 0x6e, 0xca, 0x14, 0x7c, 0x67, 0xc4, 0xf1, + 0x75, 0x61, 0xf5, 0x28, 0x33, 0xda, 0xa7, 0xa1, 0xdf, 0x92, 0x26, 0x09, 0xc7, 0xaf, 0x67, 0x1d, + 0x6f, 0x1a, 0xaf, 0x1b, 0x5f, 0xb5, 0x13, 0xfe, 0x5a, 0x03, 0x6b, 0x7e, 0xe8, 0x98, 0xb1, 0xeb, + 0x13, 0xf3, 0xd8, 0x0d, 0x9c, 0xf0, 0xd8, 0x64, 0xe8, 0x35, 0x99, 0xb0, 0x9f, 0x9d, 0x73, 0xbc, + 0x66, 0x58, 0xc7, 0x07, 0xa1, 0xf3, 0xd8, 0xf5, 0xc9, 0x13, 0xc9, 0x8a, 0x77, 0xf8, 0xb2, 0x5f, + 0x42, 0xf2, 0x11, 0xb4, 0x0c, 0x67, 0x99, 0x3b, 0x1d, 0x36, 0x26, 0xbd, 0x18, 0x15, 0x1f, 0xf0, + 0xb9, 0x06, 0x36, 0xd2, 0x6b, 0x62, 0xf7, 0xa9, 0xd0, 0x66, 0x1e, 0x53, 0x37, 0x26, 0x0c, 0xbd, + 0x2e, 0xc5, 0xfc, 0x48, 0xb4, 0x5e, 0x55, 0xf0, 0x29, 0xff, 0x44, 0xd2, 0x09, 0xc7, 0xb7, 0x0a, + 0xb7, 0xa6, 0xc4, 0x15, 0x2e, 0xcf, 0x4e, 0xe1, 0xee, 0x68, 0x3b, 0xc6, 0x34, 0x4f, 0xa2, 0x89, + 0x65, 0xb5, 0xdd, 0x11, 0x5f, 0x4c, 0xa8, 0x36, 0x6e, 0x62, 0x29, 0xb1, 0x2f, 0xf0, 0xfc, 0xf2, + 0x17, 0x41, 0xdd, 0x28, 0xd9, 0x40, 0x0f, 0xac, 0xca, 0x2f, 0x59, 0x53, 0xf4, 0x02, 0x53, 0xf5, + 0x57, 0x2c, 0xfb, 0xeb, 0xb5, 0xac, 0xbf, 0x36, 0x05, 0x3f, 0x6e, 0xb2, 0x72, 0xb8, 0x6f, 0x97, + 0xb0, 0x3c, 0xb3, 0x65, 0x58, 0x37, 0x2a, 0x76, 0xf0, 0x33, 0x0d, 0xac, 0xc9, 0x12, 0x92, 0x1f, + 0xc2, 0xa6, 0xfa, 0x12, 0x46, 0x75, 0x19, 0x6f, 0x5d, 0x7c, 0x48, 0xec, 0x86, 0xd1, 0xc0, 0x10, + 0xdc, 0x81, 0xa4, 0x9a, 0x0f, 0xc5, 0x28, 0x66, 0x97, 0xc1, 0x84, 0xe3, 0xad, 0xbc, 0x8c, 0x0a, + 0x78, 0x21, 0x8d, 0x2c, 0xb6, 0x02, 0xc7, 0xa2, 0x8e, 0x78, 0xff, 0xcf, 0x65, 0x0b, 0xa3, 0xea, + 0x08, 0xfe, 0x59, 0xc8, 0xb1, 0x44, 0x03, 0x25, 0x01, 0x73, 0x63, 0xf7, 0xa9, 0xc8, 0x28, 0x7a, + 0x43, 0xa6, 0xf3, 0x44, 0xcc, 0x85, 0xbb, 0x16, 0x23, 0x87, 0x19, 0xb7, 0x2f, 0xe7, 0x42, 0xbb, + 0x0c, 0x25, 0x1c, 0x6f, 0x28, 0x31, 0x65, 0x5c, 0xcc, 0x40, 0x13, 0xb6, 0x93, 0x90, 0x18, 0x03, + 0x2b, 0x41, 0x8c, 0x8a, 0x0d, 0x83, 0x7f, 0xd2, 0xc0, 0x6a, 0x27, 0xf4, 0xbc, 0xf0, 0xd8, 0xfc, + 0xa4, 0x1f, 0xd8, 0x62, 0x1c, 0x61, 0x48, 0x1f, 0xab, 0xfc, 0x61, 0x06, 0x7e, 0xc0, 0xf6, 0x5c, + 0xca, 0x84, 0xca, 0x4f, 0xca, 0x50, 0xae, 0xb2, 0x82, 0x4b, 0x95, 0x55, 0xdb, 0x49, 0x48, 0xa8, + 0xac, 0x04, 0x31, 0x56, 0x94, 0xa2, 0x1c, 0x86, 0x8f, 0xc0, 0xb2, 0xa8, 0xa8, 0x71, 0x77, 0x40, + 0x6f, 0x4a, 0x89, 0xe2, 0xfb, 0x6a, 0x49, 0x30, 0xf9, 0xbd, 0x4e, 0x38, 0x5e, 0x57, 0x2f, 0xbf, + 0x22, 0xaa, 0x1b, 0x65, 0x2b, 0x78, 0x04, 0xe6, 0x29, 0xb1, 0x1c, 0x33, 0x0c, 0xbc, 0x01, 0xfa, + 0xeb, 0xbe, 0x74, 0x76, 0x70, 0xce, 0x31, 0xdc, 0x23, 0x11, 0x25, 0xb6, 0x15, 0x13, 0xc7, 0x20, + 0x96, 0xf3, 0x28, 0xf0, 0x06, 0x23, 0x8e, 0xb5, 0xf7, 0xf2, 0xbf, 0x03, 0x68, 0x28, 0xe7, 0xcd, + 0x77, 0x43, 0xdf, 0x15, 0xcd, 0x3f, 0x1e, 0xc8, 0xbf, 0x03, 0x26, 0x50, 0xa4, 0x19, 0x73, 0x34, + 0x75, 0x00, 0x7f, 0x09, 0xd6, 0x4a, 0x43, 0xa8, 0x6c, 0xc8, 0x7f, 0x13, 0x41, 0xb5, 0xe6, 0x87, + 0xe7, 0x1c, 0xa3, 0x71, 0xd0, 0x83, 0xf1, 0x28, 0xd9, 0xb2, 0xe3, 0x2c, 0x74, 0xad, 0x3a, 0x89, + 0xb6, 0xec, 0xb8, 0xa0, 0x00, 0x69, 0xc6, 0x72, 0x99, 0x84, 0x3f, 0x05, 0x57, 0xd4, 0x0b, 0x98, + 0xa1, 0x2f, 0xf6, 0x65, 0xf3, 0xf8, 0xae, 0xe8, 0x64, 0xe3, 0x40, 0x6a, 0xb0, 0x62, 0xe5, 0x87, + 0x4b, 0xb7, 0x14, 0x5c, 0xa7, 0x1d, 0x03, 0x69, 0x46, 0xe6, 0xaf, 0xf9, 0xf0, 0xc5, 0x97, 0xb5, + 0x99, 0xe1, 0x97, 0xb5, 0x99, 0x17, 0xe7, 0x35, 0x6d, 0x78, 0x5e, 0xd3, 0x7e, 0xff, 0xb2, 0x36, + 0xf3, 0xf9, 0xcb, 0x9a, 0x36, 0x7c, 0x59, 0x9b, 0xf9, 0xf7, 0xcb, 0xda, 0xcc, 0xc7, 0x6f, 0xff, + 0x1f, 0x7f, 0xc0, 0xa8, 0xfb, 0xdf, 0xbe, 0x2c, 0xff, 0x88, 0x79, 0xff, 0x7f, 0x01, 0x00, 0x00, + 0xff, 0xff, 0x16, 0x42, 0xde, 0x46, 0xa6, 0x13, 0x00, 0x00, } func (m *FolderDeviceConfiguration) Marshal() (dAtA []byte, err error) { @@ -383,6 +386,18 @@ func (m *FolderConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0xc0 } + if m.SyncOwnership { + i-- + if m.SyncOwnership { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x98 + } if m.JunctionsAsDirs { i-- if m.JunctionsAsDirs { @@ -817,6 +832,9 @@ func (m *FolderConfiguration) ProtoSize() (n int) { if m.JunctionsAsDirs { n += 3 } + if m.SyncOwnership { + n += 3 + } if m.DeprecatedReadOnly { n += 4 } @@ -1764,6 +1782,26 @@ func (m *FolderConfiguration) Unmarshal(dAtA []byte) error { } } m.JunctionsAsDirs = bool(v != 0) + case 35: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncOwnership", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFolderconfiguration + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SyncOwnership = bool(v != 0) case 9000: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedReadOnly", wireType) diff --git a/lib/db/db_test.go b/lib/db/db_test.go index b76bb1c50b8..947188c20c4 100644 --- a/lib/db/db_test.go +++ b/lib/db/db_test.go @@ -212,7 +212,7 @@ func TestUpdate0to3(t *testing.T) { t.Error("Unexpected additional file via sequence", f.FileName()) return true } - if e := haveUpdate0to3[protocol.LocalDeviceID][0]; f.IsEquivalentOptional(e, 0, true, true, 0) { + if e := haveUpdate0to3[protocol.LocalDeviceID][0]; f.IsEquivalentOptional(e, protocol.FileInfoComparison{IgnorePerms: true, IgnoreBlocks: true}) { found = true } else { t.Errorf("Wrong file via sequence, got %v, expected %v", f, e) @@ -281,7 +281,7 @@ func TestUpdate0to3(t *testing.T) { } f := fi.(protocol.FileInfo) delete(need, f.Name) - if !f.IsEquivalentOptional(e, 0, true, true, 0) { + if !f.IsEquivalentOptional(e, protocol.FileInfoComparison{IgnorePerms: true, IgnoreBlocks: true}) { t.Errorf("Wrong needed file, got %v, expected %v", f, e) } } diff --git a/lib/db/structs.pb.go b/lib/db/structs.pb.go index a72e3756b51..8703708c4b7 100644 --- a/lib/db/structs.pb.go +++ b/lib/db/structs.pb.go @@ -122,6 +122,7 @@ type FileInfoTruncated struct { Permissions uint32 `protobuf:"varint,4,opt,name=permissions,proto3" json:"permissions" xml:"permissions"` ModifiedNs int `protobuf:"varint,11,opt,name=modified_ns,json=modifiedNs,proto3,casttype=int" json:"modifiedNs" xml:"modifiedNs"` RawBlockSize int `protobuf:"varint,13,opt,name=block_size,json=blockSize,proto3,casttype=int" json:"blockSize" xml:"blockSize"` + Platform protocol.PlatformData `protobuf:"bytes,14,opt,name=platform,proto3" json:"platform" xml:"platform"` // see bep.proto LocalFlags uint32 `protobuf:"varint,1000,opt,name=local_flags,json=localFlags,proto3" json:"localFlags" xml:"localFlags"` VersionHash []byte `protobuf:"bytes,1001,opt,name=version_hash,json=versionHash,proto3" json:"versionHash" xml:"versionHash"` @@ -495,100 +496,102 @@ func init() { func init() { proto.RegisterFile("lib/db/structs.proto", fileDescriptor_5465d80e8cba02e3) } var fileDescriptor_5465d80e8cba02e3 = []byte{ - // 1476 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4d, 0x6f, 0xdb, 0x46, - 0x13, 0x36, 0x2d, 0xf9, 0x43, 0x2b, 0xf9, 0x8b, 0x79, 0x6d, 0xe8, 0xf5, 0xfb, 0x56, 0xab, 0x6e, - 0x1c, 0x40, 0xfd, 0x80, 0x0c, 0x38, 0x88, 0x51, 0x04, 0x68, 0x83, 0x30, 0xae, 0x13, 0x07, 0x69, - 0x52, 0xac, 0x83, 0xa4, 0x68, 0x0f, 0x82, 0x48, 0xae, 0x65, 0x22, 0x14, 0xa9, 0x72, 0x69, 0x3b, - 0xca, 0xad, 0x97, 0x02, 0xbd, 0x05, 0x41, 0x0f, 0x45, 0x51, 0x14, 0x39, 0xf5, 0x27, 0xf4, 0x17, - 0x14, 0x45, 0x8e, 0x3e, 0x16, 0x3d, 0xb0, 0x88, 0x7d, 0x69, 0x75, 0xd4, 0xa9, 0xe8, 0xa9, 0xd8, - 0xd9, 0xe5, 0x92, 0xb2, 0x91, 0x22, 0x49, 0x7d, 0xd3, 0x3c, 0xf3, 0xcc, 0x88, 0x9c, 0x7d, 0x66, - 0x76, 0x88, 0xfe, 0xe3, 0x7b, 0xf6, 0xaa, 0x6b, 0xaf, 0xf2, 0x38, 0xda, 0x73, 0x62, 0xde, 0xec, - 0x45, 0x61, 0x1c, 0x9a, 0xe3, 0xae, 0xbd, 0x7c, 0x3e, 0x62, 0xbd, 0x90, 0xaf, 0x02, 0x60, 0xef, - 0xed, 0xac, 0x76, 0xc2, 0x4e, 0x08, 0x06, 0xfc, 0x92, 0xc4, 0x65, 0xdc, 0x09, 0xc3, 0x8e, 0xcf, - 0x32, 0x56, 0xec, 0x75, 0x19, 0x8f, 0xdb, 0xdd, 0x9e, 0x22, 0x2c, 0x89, 0xfc, 0xf0, 0xd3, 0x09, - 0xfd, 0x55, 0x9b, 0xa5, 0x78, 0x89, 0x3d, 0x8c, 0xe5, 0x4f, 0xf2, 0xfd, 0x38, 0x2a, 0x6f, 0x7a, - 0x3e, 0xbb, 0xc7, 0x22, 0xee, 0x85, 0x81, 0x79, 0x0b, 0x4d, 0xed, 0xcb, 0x9f, 0x55, 0xa3, 0x6e, - 0x34, 0xca, 0x6b, 0xf3, 0xcd, 0x34, 0x41, 0xf3, 0x1e, 0x73, 0xe2, 0x30, 0xb2, 0xea, 0xcf, 0x12, - 0x3c, 0x36, 0x48, 0x70, 0x4a, 0x1c, 0x26, 0x78, 0xe6, 0x61, 0xd7, 0xbf, 0x4c, 0x94, 0x4d, 0x68, - 0xea, 0x31, 0xd7, 0xd1, 0x94, 0xcb, 0x7c, 0x16, 0x33, 0xb7, 0x3a, 0x5e, 0x37, 0x1a, 0xd3, 0xd6, - 0xff, 0x45, 0x9c, 0x82, 0x74, 0x9c, 0xb2, 0x09, 0x4d, 0x3d, 0xe6, 0x25, 0x11, 0xb7, 0xef, 0x39, - 0x8c, 0x57, 0x0b, 0xf5, 0x42, 0xa3, 0x62, 0xfd, 0x4f, 0xc6, 0x01, 0x34, 0x4c, 0x70, 0x45, 0xc5, - 0x09, 0x1b, 0xc2, 0xc0, 0x61, 0x52, 0x34, 0xe7, 0x05, 0xfb, 0x6d, 0xdf, 0x73, 0x5b, 0x69, 0x78, - 0x11, 0xc2, 0xdf, 0x1a, 0x24, 0x78, 0x56, 0xb9, 0x36, 0x74, 0x96, 0x73, 0x90, 0x65, 0x04, 0x26, - 0xf4, 0x04, 0x8d, 0x7c, 0x61, 0xa0, 0xb2, 0x2a, 0xce, 0x2d, 0x8f, 0xc7, 0xa6, 0x8f, 0xa6, 0xd5, - 0xdb, 0xf1, 0xaa, 0x51, 0x2f, 0x34, 0xca, 0x6b, 0x73, 0x4d, 0xd7, 0x6e, 0xe6, 0x6a, 0x68, 0x5d, - 0x11, 0x05, 0x3a, 0x4a, 0x70, 0x99, 0xb6, 0x0f, 0x14, 0xc6, 0x07, 0x09, 0xd6, 0x71, 0xa7, 0x0a, - 0xf6, 0xe4, 0x70, 0x25, 0xcf, 0xa5, 0x9a, 0x79, 0xb9, 0xf8, 0xcd, 0x53, 0x3c, 0x46, 0xfe, 0x44, - 0x68, 0x41, 0xfc, 0xc1, 0x56, 0xb0, 0x13, 0xde, 0x8d, 0xf6, 0x02, 0xa7, 0x2d, 0x8a, 0xf4, 0x36, - 0x2a, 0x06, 0xed, 0x2e, 0x83, 0x73, 0x2a, 0x59, 0x4b, 0x83, 0x04, 0x83, 0x3d, 0x4c, 0x30, 0x82, - 0xec, 0xc2, 0x20, 0x14, 0x30, 0xc1, 0xe5, 0xde, 0x23, 0x56, 0x2d, 0xd4, 0x8d, 0x46, 0x41, 0x72, - 0x85, 0xad, 0xb9, 0xc2, 0x20, 0x14, 0x30, 0xf3, 0x0a, 0x42, 0xdd, 0xd0, 0xf5, 0x76, 0x3c, 0xe6, - 0xb6, 0x78, 0x75, 0x02, 0x22, 0xea, 0x83, 0x04, 0x97, 0x52, 0x74, 0x7b, 0x98, 0xe0, 0x39, 0x08, - 0xd3, 0x08, 0xa1, 0x99, 0xd7, 0xfc, 0xd1, 0x40, 0x65, 0x9d, 0xc1, 0xee, 0x57, 0x2b, 0x75, 0xa3, - 0x51, 0xb4, 0xbe, 0x36, 0x44, 0x59, 0x7e, 0x4d, 0xf0, 0xc5, 0x8e, 0x17, 0xef, 0xee, 0xd9, 0x4d, - 0x27, 0xec, 0xae, 0xf2, 0x7e, 0xe0, 0xc4, 0xbb, 0x5e, 0xd0, 0xc9, 0xfd, 0xca, 0x8b, 0xb6, 0xb9, - 0xbd, 0x1b, 0x46, 0xf1, 0xd6, 0xc6, 0x20, 0xc1, 0xfa, 0xa1, 0xac, 0xfe, 0x30, 0xc1, 0xf3, 0x23, - 0xff, 0x6f, 0xf5, 0xc9, 0xb7, 0x87, 0x2b, 0xaf, 0x93, 0x98, 0xe6, 0xd2, 0xe6, 0xc5, 0x5f, 0xfa, - 0xf7, 0xe2, 0xbf, 0x8c, 0xa6, 0x39, 0xfb, 0x7c, 0x8f, 0x05, 0x0e, 0xab, 0x22, 0xa8, 0x62, 0x4d, - 0xa8, 0x20, 0xc5, 0x86, 0x09, 0x9e, 0x95, 0xb5, 0x57, 0x00, 0xa1, 0xda, 0x67, 0xde, 0x41, 0xb3, - 0xbc, 0xdf, 0xf5, 0xbd, 0xe0, 0x41, 0x2b, 0x6e, 0x47, 0x1d, 0x16, 0x57, 0x17, 0xe0, 0x94, 0x1b, - 0x83, 0x04, 0xcf, 0x28, 0xcf, 0x5d, 0x70, 0x68, 0x1d, 0x8f, 0xa0, 0x84, 0x8e, 0xb2, 0xcc, 0x6b, - 0xa8, 0x6c, 0xfb, 0xa1, 0xf3, 0x80, 0xb7, 0x76, 0xdb, 0x7c, 0xb7, 0x6a, 0xd6, 0x8d, 0x46, 0xc5, - 0x22, 0xa2, 0xac, 0x12, 0xbe, 0xd1, 0xe6, 0xbb, 0xba, 0xac, 0x19, 0x44, 0x68, 0xce, 0x6f, 0x7e, - 0x80, 0x4a, 0x2c, 0x70, 0xa2, 0x7e, 0x4f, 0x34, 0xf4, 0x39, 0x48, 0x01, 0xc2, 0xd0, 0xa0, 0x16, - 0x86, 0x46, 0x08, 0xcd, 0xbc, 0xa6, 0x85, 0x8a, 0x71, 0xbf, 0xc7, 0x60, 0x16, 0xcc, 0xae, 0x2d, - 0x65, 0xc5, 0xd5, 0xe2, 0xee, 0xf7, 0x98, 0x54, 0xa7, 0xe0, 0x69, 0x75, 0x0a, 0x83, 0x50, 0xc0, - 0xcc, 0x4d, 0x54, 0xee, 0xb1, 0xa8, 0xeb, 0x71, 0xd9, 0x82, 0xc5, 0xba, 0xd1, 0x98, 0xb1, 0x56, - 0x06, 0x09, 0xce, 0xc3, 0xc3, 0x04, 0x2f, 0x40, 0x64, 0x0e, 0x23, 0x34, 0xcf, 0x30, 0x6f, 0xe6, - 0x34, 0x1a, 0xf0, 0x6a, 0xb9, 0x6e, 0x34, 0x26, 0x60, 0x4e, 0x68, 0x41, 0xdc, 0xe6, 0xa7, 0x74, - 0x76, 0x9b, 0x93, 0xbf, 0x12, 0x5c, 0xf0, 0x82, 0x98, 0xe6, 0x68, 0xe6, 0x0e, 0x92, 0x55, 0x6a, - 0x41, 0x8f, 0xcd, 0x40, 0xaa, 0xeb, 0x47, 0x09, 0xae, 0xd0, 0xf6, 0x81, 0x25, 0x1c, 0xdb, 0xde, - 0x23, 0x26, 0x0a, 0x65, 0xa7, 0x86, 0x2e, 0x94, 0x46, 0xd2, 0xc4, 0x4f, 0x0e, 0x57, 0x46, 0xc2, - 0x68, 0x16, 0x64, 0x6e, 0xa0, 0xb2, 0x1f, 0x3a, 0x6d, 0xbf, 0xb5, 0xe3, 0xb7, 0x3b, 0xbc, 0xfa, - 0xfb, 0x14, 0xbc, 0x3c, 0x9c, 0x22, 0xe0, 0x9b, 0x02, 0xd6, 0x0f, 0x9d, 0x41, 0x84, 0xe6, 0xfc, - 0xe6, 0x0d, 0x54, 0x51, 0x12, 0x95, 0x5a, 0xf8, 0x63, 0x0a, 0x4e, 0x12, 0x6a, 0xa8, 0x1c, 0x4a, - 0x0d, 0x0b, 0x79, 0x65, 0x4b, 0x39, 0xe4, 0x19, 0xf9, 0xf1, 0x3e, 0xf9, 0x2a, 0xe3, 0x9d, 0xa2, - 0x29, 0x35, 0x65, 0xab, 0x53, 0x10, 0xf7, 0xde, 0x51, 0x82, 0x11, 0x6d, 0x1f, 0x6c, 0x49, 0x54, - 0x64, 0x51, 0x04, 0x9d, 0x45, 0xd9, 0x62, 0x56, 0xe6, 0x98, 0x34, 0xe5, 0x89, 0x8e, 0x09, 0xc2, - 0x56, 0x5e, 0x1a, 0xd3, 0x90, 0x1a, 0x3a, 0x26, 0x08, 0x3f, 0x1e, 0x11, 0x87, 0xec, 0x98, 0x11, - 0x94, 0xd0, 0x51, 0x96, 0x1a, 0xbd, 0xf7, 0x51, 0x09, 0x8e, 0x02, 0x66, 0xff, 0x4d, 0x34, 0x29, - 0xbb, 0x41, 0x4d, 0xfe, 0x73, 0x99, 0x82, 0x81, 0x24, 0x24, 0x6c, 0xbd, 0xa1, 0x26, 0x84, 0xa2, - 0x0e, 0x13, 0x5c, 0xce, 0x4e, 0x9a, 0x50, 0x05, 0x93, 0x1f, 0x0c, 0xb4, 0xb8, 0x15, 0xb8, 0x5e, - 0xc4, 0x9c, 0x58, 0xd5, 0x93, 0xf1, 0x3b, 0x81, 0xdf, 0x3f, 0x9b, 0x56, 0x3d, 0xb3, 0x43, 0x26, - 0xdf, 0x15, 0xd1, 0xe4, 0xb5, 0x70, 0x2f, 0x88, 0xb9, 0x79, 0x09, 0x4d, 0xec, 0x78, 0x3e, 0xe3, - 0x70, 0xe5, 0x4c, 0x58, 0x78, 0x90, 0x60, 0x09, 0xe8, 0x97, 0x04, 0x4b, 0xf7, 0x88, 0x74, 0x9a, - 0x1f, 0xa1, 0xb2, 0x7c, 0xcf, 0x30, 0xf2, 0x18, 0x87, 0xee, 0x9f, 0xb0, 0xde, 0x11, 0x4f, 0x92, - 0x83, 0xf5, 0x93, 0xe4, 0x30, 0x9d, 0x28, 0x4f, 0x34, 0xaf, 0xa2, 0x69, 0x35, 0xdb, 0x38, 0xdc, - 0x67, 0x13, 0xd6, 0x05, 0x98, 0xab, 0x0a, 0xcb, 0xe6, 0xaa, 0x02, 0x74, 0x16, 0x4d, 0x31, 0xdf, - 0xcf, 0x84, 0x5b, 0x84, 0x0c, 0xe7, 0xff, 0x49, 0xb8, 0x69, 0xbc, 0xd6, 0x6f, 0x13, 0x4d, 0xd8, - 0xfd, 0x98, 0xa5, 0x97, 0x63, 0x55, 0xd4, 0x01, 0x80, 0xec, 0xb0, 0x85, 0x45, 0xa8, 0x44, 0x47, - 0x6e, 0x82, 0xc9, 0x57, 0xbc, 0x09, 0xb6, 0x51, 0x49, 0xee, 0x32, 0x2d, 0xcf, 0x85, 0x4b, 0xa0, - 0x62, 0xad, 0x1f, 0x25, 0x78, 0x5a, 0xee, 0x27, 0x70, 0x33, 0x4e, 0x4b, 0xc2, 0x96, 0xab, 0x13, - 0xa5, 0x80, 0xe8, 0x16, 0xcd, 0xa4, 0x9a, 0x27, 0x24, 0x96, 0x1f, 0x24, 0xe6, 0xeb, 0xcc, 0x11, - 0xd5, 0x20, 0x5f, 0x1a, 0xa8, 0x24, 0xe5, 0xb1, 0xcd, 0x62, 0xf3, 0x2a, 0x9a, 0x74, 0xc0, 0x50, - 0x1d, 0x82, 0xc4, 0x6e, 0x24, 0xdd, 0x59, 0x63, 0x48, 0x86, 0xae, 0x15, 0x98, 0x84, 0x2a, 0x58, - 0x0c, 0x15, 0x27, 0x62, 0xed, 0x74, 0x67, 0x2c, 0xc8, 0xa1, 0xa2, 0x20, 0x7d, 0x36, 0xca, 0x26, - 0x34, 0xf5, 0x90, 0xaf, 0xc6, 0xd1, 0x62, 0x6e, 0x0b, 0xdb, 0x60, 0xbd, 0x88, 0xc9, 0x45, 0xe9, - 0x6c, 0x77, 0xda, 0x35, 0x34, 0x29, 0xeb, 0x08, 0x8f, 0x57, 0xb1, 0x96, 0xc5, 0x2b, 0x49, 0xe4, - 0xd4, 0x66, 0xaa, 0x70, 0xf1, 0x4e, 0xe9, 0xc0, 0x2b, 0x64, 0x83, 0xf2, 0x45, 0x23, 0x2e, 0x1b, - 0x6a, 0xeb, 0xa3, 0x3a, 0x7d, 0xd9, 0x01, 0x4b, 0x0e, 0xd0, 0x62, 0x6e, 0x67, 0xcd, 0x95, 0xe2, - 0x93, 0x53, 0xdb, 0xeb, 0x7f, 0x4f, 0x6c, 0xaf, 0x19, 0xd9, 0x7a, 0x53, 0x15, 0xe5, 0xc5, 0x8b, - 0xeb, 0xa9, 0x4d, 0xf5, 0xe7, 0x71, 0x34, 0x7b, 0xc7, 0xe6, 0x2c, 0xda, 0x67, 0xee, 0x66, 0xe8, - 0xbb, 0x2c, 0x32, 0x6f, 0xa3, 0xa2, 0xf8, 0x2e, 0x51, 0xa5, 0x5f, 0x6e, 0xca, 0x8f, 0x96, 0x66, - 0xfa, 0xd1, 0xd2, 0xbc, 0x9b, 0x7e, 0xb4, 0x58, 0x35, 0xf5, 0x7f, 0xc0, 0xcf, 0x2e, 0x7f, 0xaf, - 0xcb, 0xc8, 0xe3, 0xdf, 0xb0, 0x41, 0x01, 0x17, 0xcd, 0xe7, 0xb7, 0x6d, 0xe6, 0x43, 0xf9, 0x4b, - 0xb2, 0xf9, 0x00, 0xd0, 0x82, 0x02, 0x8b, 0x50, 0x89, 0x9a, 0x9f, 0xa1, 0x85, 0x88, 0x39, 0xcc, - 0xdb, 0x67, 0xad, 0x6c, 0x79, 0x91, 0xa7, 0xd0, 0x1c, 0x24, 0x78, 0x5e, 0x39, 0x3f, 0xcc, 0xed, - 0x30, 0x4b, 0x90, 0xe6, 0xa4, 0x83, 0xd0, 0x53, 0x5c, 0xf3, 0x3e, 0x9a, 0x8f, 0x58, 0x37, 0x8c, - 0xf3, 0xb9, 0xe5, 0x49, 0xbd, 0x3b, 0x48, 0xf0, 0x9c, 0xf4, 0xe5, 0x53, 0x2f, 0xaa, 0xd4, 0x23, - 0x38, 0xa1, 0x27, 0x99, 0xe4, 0x27, 0x23, 0x2b, 0xa4, 0x6c, 0xe0, 0x33, 0x2f, 0x64, 0xfa, 0xfd, - 0x30, 0xfe, 0x12, 0xdf, 0x0f, 0xeb, 0x68, 0xaa, 0xed, 0xba, 0x11, 0xe3, 0x72, 0xe4, 0x96, 0xa4, - 0x10, 0x15, 0xa4, 0x65, 0xa1, 0x6c, 0x42, 0x53, 0x8f, 0x75, 0xfd, 0xd9, 0xf3, 0xda, 0xd8, 0xe1, - 0xf3, 0xda, 0xd8, 0xb3, 0xa3, 0x9a, 0x71, 0x78, 0x54, 0x33, 0x1e, 0x1f, 0xd7, 0xc6, 0x9e, 0x1e, - 0xd7, 0x8c, 0xc3, 0xe3, 0xda, 0xd8, 0x2f, 0xc7, 0xb5, 0xb1, 0x4f, 0x2f, 0xbc, 0xc4, 0xd2, 0xee, - 0xda, 0xf6, 0x24, 0xbc, 0xe6, 0xc5, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xb3, 0xa4, 0xea, 0xfc, - 0x33, 0x0f, 0x00, 0x00, + // 1510 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcd, 0x6f, 0xdb, 0x46, + 0x16, 0x37, 0x2d, 0xd9, 0x96, 0x46, 0xf2, 0x17, 0xb3, 0x36, 0xb8, 0xde, 0x5d, 0x8d, 0x76, 0xe2, + 0x00, 0xda, 0x0f, 0xc8, 0x80, 0x83, 0x18, 0x8b, 0x00, 0xdb, 0x20, 0x8c, 0xeb, 0xc4, 0x41, 0x9a, + 0x04, 0xe3, 0x20, 0x29, 0xda, 0x83, 0xc0, 0x8f, 0xb1, 0x4c, 0x84, 0x22, 0x55, 0x92, 0xb6, 0xa3, + 0xdc, 0x7a, 0x29, 0xd0, 0x5b, 0x10, 0xf4, 0x50, 0x14, 0x45, 0x91, 0x53, 0xff, 0x84, 0xfe, 0x05, + 0x45, 0x91, 0xa3, 0x8f, 0x45, 0x0f, 0x2c, 0x62, 0x5f, 0x5a, 0x1d, 0x75, 0xec, 0xa9, 0x98, 0x37, + 0xc3, 0x21, 0x65, 0x23, 0x45, 0x92, 0xfa, 0xc6, 0xf7, 0x7b, 0xbf, 0xf7, 0x24, 0xbe, 0xf9, 0xbd, + 0x37, 0x8f, 0xe8, 0x2f, 0xbe, 0x67, 0xaf, 0xb9, 0xf6, 0x5a, 0x9c, 0x44, 0xfb, 0x4e, 0x12, 0xb7, + 0xfb, 0x51, 0x98, 0x84, 0xfa, 0xa4, 0x6b, 0xaf, 0x5c, 0x8c, 0x58, 0x3f, 0x8c, 0xd7, 0x00, 0xb0, + 0xf7, 0x77, 0xd7, 0xba, 0x61, 0x37, 0x04, 0x03, 0x9e, 0x04, 0x71, 0x05, 0x77, 0xc3, 0xb0, 0xeb, + 0xb3, 0x9c, 0x95, 0x78, 0x3d, 0x16, 0x27, 0x56, 0xaf, 0x2f, 0x09, 0xcb, 0x3c, 0x3f, 0x3c, 0x3a, + 0xa1, 0xbf, 0x66, 0xb3, 0x0c, 0xaf, 0xb2, 0x27, 0x89, 0x78, 0x24, 0xdf, 0x4c, 0xa2, 0xda, 0x96, + 0xe7, 0xb3, 0x87, 0x2c, 0x8a, 0xbd, 0x30, 0xd0, 0xef, 0xa0, 0x99, 0x03, 0xf1, 0x68, 0x68, 0x4d, + 0xad, 0x55, 0x5b, 0x5f, 0x68, 0x67, 0x09, 0xda, 0x0f, 0x99, 0x93, 0x84, 0x91, 0xd9, 0x7c, 0x99, + 0xe2, 0x89, 0x61, 0x8a, 0x33, 0xe2, 0x28, 0xc5, 0xb3, 0x4f, 0x7a, 0xfe, 0x55, 0x22, 0x6d, 0x42, + 0x33, 0x8f, 0xbe, 0x81, 0x66, 0x5c, 0xe6, 0xb3, 0x84, 0xb9, 0xc6, 0x64, 0x53, 0x6b, 0x55, 0xcc, + 0xbf, 0xf3, 0x38, 0x09, 0xa9, 0x38, 0x69, 0x13, 0x9a, 0x79, 0xf4, 0x2b, 0x3c, 0xee, 0xc0, 0x73, + 0x58, 0x6c, 0x94, 0x9a, 0xa5, 0x56, 0xdd, 0xfc, 0x9b, 0x88, 0x03, 0x68, 0x94, 0xe2, 0xba, 0x8c, + 0xe3, 0x36, 0x84, 0x81, 0x43, 0xa7, 0x68, 0xde, 0x0b, 0x0e, 0x2c, 0xdf, 0x73, 0x3b, 0x59, 0x78, + 0x19, 0xc2, 0xff, 0x35, 0x4c, 0xf1, 0x9c, 0x74, 0x6d, 0xaa, 0x2c, 0x17, 0x20, 0xcb, 0x18, 0x4c, + 0xe8, 0x29, 0x1a, 0xf9, 0x54, 0x43, 0x35, 0x59, 0x9c, 0x3b, 0x5e, 0x9c, 0xe8, 0x3e, 0xaa, 0xc8, + 0xb7, 0x8b, 0x0d, 0xad, 0x59, 0x6a, 0xd5, 0xd6, 0xe7, 0xdb, 0xae, 0xdd, 0x2e, 0xd4, 0xd0, 0xbc, + 0xc6, 0x0b, 0x74, 0x9c, 0xe2, 0x1a, 0xb5, 0x0e, 0x25, 0x16, 0x0f, 0x53, 0xac, 0xe2, 0xce, 0x14, + 0xec, 0xf9, 0xd1, 0x6a, 0x91, 0x4b, 0x15, 0xf3, 0x6a, 0xf9, 0xcb, 0x17, 0x78, 0x82, 0x1c, 0xd5, + 0xd0, 0x22, 0xff, 0x81, 0xed, 0x60, 0x37, 0x7c, 0x10, 0xed, 0x07, 0x8e, 0xc5, 0x8b, 0xf4, 0x6f, + 0x54, 0x0e, 0xac, 0x1e, 0x83, 0x73, 0xaa, 0x9a, 0xcb, 0xc3, 0x14, 0x83, 0x3d, 0x4a, 0x31, 0x82, + 0xec, 0xdc, 0x20, 0x14, 0x30, 0xce, 0x8d, 0xbd, 0xa7, 0xcc, 0x28, 0x35, 0xb5, 0x56, 0x49, 0x70, + 0xb9, 0xad, 0xb8, 0xdc, 0x20, 0x14, 0x30, 0xfd, 0x1a, 0x42, 0xbd, 0xd0, 0xf5, 0x76, 0x3d, 0xe6, + 0x76, 0x62, 0x63, 0x0a, 0x22, 0x9a, 0xc3, 0x14, 0x57, 0x33, 0x74, 0x67, 0x94, 0xe2, 0x79, 0x08, + 0x53, 0x08, 0xa1, 0xb9, 0x57, 0xff, 0x4e, 0x43, 0x35, 0x95, 0xc1, 0x1e, 0x18, 0xf5, 0xa6, 0xd6, + 0x2a, 0x9b, 0x5f, 0x68, 0xbc, 0x2c, 0x3f, 0xa5, 0xf8, 0x72, 0xd7, 0x4b, 0xf6, 0xf6, 0xed, 0xb6, + 0x13, 0xf6, 0xd6, 0xe2, 0x41, 0xe0, 0x24, 0x7b, 0x5e, 0xd0, 0x2d, 0x3c, 0x15, 0x45, 0xdb, 0xde, + 0xd9, 0x0b, 0xa3, 0x64, 0x7b, 0x73, 0x98, 0x62, 0xf5, 0xa7, 0xcc, 0xc1, 0x28, 0xc5, 0x0b, 0x63, + 0xbf, 0x6f, 0x0e, 0xc8, 0x57, 0x47, 0xab, 0xef, 0x92, 0x98, 0x16, 0xd2, 0x16, 0xc5, 0x5f, 0xfd, + 0xf3, 0xe2, 0xbf, 0x8a, 0x2a, 0x31, 0xfb, 0x64, 0x9f, 0x05, 0x0e, 0x33, 0x10, 0x54, 0xb1, 0xc1, + 0x55, 0x90, 0x61, 0xa3, 0x14, 0xcf, 0x89, 0xda, 0x4b, 0x80, 0x50, 0xe5, 0xd3, 0xef, 0xa1, 0xb9, + 0x78, 0xd0, 0xf3, 0xbd, 0xe0, 0x71, 0x27, 0xb1, 0xa2, 0x2e, 0x4b, 0x8c, 0x45, 0x38, 0xe5, 0xd6, + 0x30, 0xc5, 0xb3, 0xd2, 0xf3, 0x00, 0x1c, 0x4a, 0xc7, 0x63, 0x28, 0xa1, 0xe3, 0x2c, 0xfd, 0x06, + 0xaa, 0xd9, 0x7e, 0xe8, 0x3c, 0x8e, 0x3b, 0x7b, 0x56, 0xbc, 0x67, 0xe8, 0x4d, 0xad, 0x55, 0x37, + 0x09, 0x2f, 0xab, 0x80, 0x6f, 0x59, 0xf1, 0x9e, 0x2a, 0x6b, 0x0e, 0x11, 0x5a, 0xf0, 0xeb, 0xef, + 0xa1, 0x2a, 0x0b, 0x9c, 0x68, 0xd0, 0xe7, 0x0d, 0x7d, 0x01, 0x52, 0x80, 0x30, 0x14, 0xa8, 0x84, + 0xa1, 0x10, 0x42, 0x73, 0xaf, 0x6e, 0xa2, 0x72, 0x32, 0xe8, 0x33, 0x98, 0x05, 0x73, 0xeb, 0xcb, + 0x79, 0x71, 0x95, 0xb8, 0x07, 0x7d, 0x26, 0xd4, 0xc9, 0x79, 0x4a, 0x9d, 0xdc, 0x20, 0x14, 0x30, + 0x7d, 0x0b, 0xd5, 0xfa, 0x2c, 0xea, 0x79, 0xb1, 0x68, 0xc1, 0x72, 0x53, 0x6b, 0xcd, 0x9a, 0xab, + 0xc3, 0x14, 0x17, 0xe1, 0x51, 0x8a, 0x17, 0x21, 0xb2, 0x80, 0x11, 0x5a, 0x64, 0xe8, 0xb7, 0x0b, + 0x1a, 0x0d, 0x62, 0xa3, 0xd6, 0xd4, 0x5a, 0x53, 0x30, 0x27, 0x94, 0x20, 0xee, 0xc6, 0x67, 0x74, + 0x76, 0x37, 0x26, 0xbf, 0xa5, 0xb8, 0xe4, 0x05, 0x09, 0x2d, 0xd0, 0xf4, 0x5d, 0x24, 0xaa, 0xd4, + 0x81, 0x1e, 0x9b, 0x85, 0x54, 0x37, 0x8f, 0x53, 0x5c, 0xa7, 0xd6, 0xa1, 0xc9, 0x1d, 0x3b, 0xde, + 0x53, 0xc6, 0x0b, 0x65, 0x67, 0x86, 0x2a, 0x94, 0x42, 0xb2, 0xc4, 0xcf, 0x8f, 0x56, 0xc7, 0xc2, + 0x68, 0x1e, 0xa4, 0x3f, 0x44, 0x95, 0xbe, 0x6f, 0x25, 0xbb, 0x61, 0xd4, 0x33, 0xe6, 0x40, 0xa0, + 0x85, 0x1a, 0xde, 0x97, 0x9e, 0x4d, 0x2b, 0xb1, 0x4c, 0x22, 0x65, 0xaa, 0xf8, 0x4a, 0x6d, 0x19, + 0x40, 0xa8, 0xf2, 0xe9, 0x9b, 0xa8, 0xe6, 0x87, 0x8e, 0xe5, 0x77, 0x76, 0x7d, 0xab, 0x1b, 0x1b, + 0xbf, 0xcc, 0x40, 0x51, 0x41, 0x1d, 0x80, 0x6f, 0x71, 0x58, 0x15, 0x23, 0x87, 0x08, 0x2d, 0xf8, + 0xf5, 0x5b, 0xa8, 0x2e, 0xa5, 0x2f, 0x34, 0xf6, 0xeb, 0x0c, 0x28, 0x04, 0xce, 0x46, 0x3a, 0xa4, + 0xca, 0x16, 0x8b, 0x1d, 0x23, 0x64, 0x56, 0x64, 0x14, 0xaf, 0x8d, 0xe9, 0xb7, 0xb9, 0x36, 0x28, + 0x9a, 0x91, 0xd3, 0xdb, 0x98, 0x81, 0xb8, 0xff, 0x1d, 0xa7, 0x18, 0x51, 0xeb, 0x70, 0x5b, 0xa0, + 0x3c, 0x8b, 0x24, 0xa8, 0x2c, 0xd2, 0xe6, 0x33, 0xb8, 0xc0, 0xa4, 0x19, 0x8f, 0x77, 0x62, 0x10, + 0x76, 0x8a, 0x92, 0xab, 0x40, 0x6a, 0xe8, 0xc4, 0x20, 0xbc, 0x3f, 0x26, 0x3a, 0xd1, 0x89, 0x63, + 0x28, 0xa1, 0xe3, 0x2c, 0x39, 0xd2, 0x1f, 0xa1, 0x2a, 0x1c, 0x31, 0xdc, 0x29, 0xb7, 0xd1, 0xb4, + 0xe8, 0x32, 0x79, 0xa3, 0x5c, 0xc8, 0x4f, 0x15, 0x48, 0xbc, 0x35, 0xcc, 0x7f, 0xc8, 0x23, 0x95, + 0xd4, 0x51, 0x8a, 0x6b, 0xb9, 0x82, 0x08, 0x95, 0x30, 0xf9, 0x56, 0x43, 0x4b, 0xdb, 0x81, 0xeb, + 0x45, 0xcc, 0x49, 0x64, 0x3d, 0x59, 0x7c, 0x2f, 0xf0, 0x07, 0xe7, 0x33, 0x02, 0xce, 0xed, 0x90, + 0xc9, 0xd7, 0x65, 0x34, 0x7d, 0x23, 0xdc, 0x0f, 0x92, 0x58, 0xbf, 0x82, 0xa6, 0x76, 0x3d, 0x9f, + 0xc5, 0x70, 0x95, 0x4d, 0x99, 0x78, 0x98, 0x62, 0x01, 0xa8, 0x97, 0x04, 0x4b, 0xf5, 0x9e, 0x70, + 0xea, 0x1f, 0xa0, 0x9a, 0x78, 0xcf, 0x30, 0xf2, 0x58, 0x0c, 0x53, 0x65, 0xca, 0xfc, 0x0f, 0xff, + 0x27, 0x05, 0x58, 0xfd, 0x93, 0x02, 0xa6, 0x12, 0x15, 0x89, 0xfa, 0x75, 0x54, 0x91, 0x33, 0x33, + 0x86, 0x7b, 0x72, 0xca, 0xbc, 0x04, 0xf3, 0x5a, 0x62, 0xf9, 0xbc, 0x96, 0x80, 0xca, 0xa2, 0x28, + 0xfa, 0xff, 0x73, 0xe1, 0x96, 0x21, 0xc3, 0xc5, 0x3f, 0x12, 0x6e, 0x16, 0xaf, 0xf4, 0xdb, 0x46, + 0x53, 0xf6, 0x20, 0x61, 0xd9, 0xa5, 0x6b, 0xf0, 0x3a, 0x00, 0x90, 0x1f, 0x36, 0xb7, 0x08, 0x15, + 0xe8, 0xd8, 0x0d, 0x33, 0xfd, 0x96, 0x37, 0xcc, 0x0e, 0xaa, 0x8a, 0x1d, 0xa9, 0xe3, 0xb9, 0x70, + 0xb9, 0xd4, 0xcd, 0x8d, 0xe3, 0x14, 0x57, 0xc4, 0xde, 0x03, 0x37, 0x6e, 0x45, 0x10, 0xb6, 0x5d, + 0x95, 0x28, 0x03, 0x78, 0xb7, 0x28, 0x26, 0x55, 0x3c, 0x2e, 0xb1, 0xe2, 0x20, 0xd1, 0xdf, 0x65, + 0x8e, 0xc8, 0x06, 0xf9, 0x4c, 0x43, 0x55, 0x21, 0x8f, 0x1d, 0x96, 0xe8, 0xd7, 0xd1, 0xb4, 0x03, + 0x86, 0xec, 0x10, 0xc4, 0x77, 0x2e, 0xe1, 0xce, 0x1b, 0x43, 0x30, 0x54, 0xad, 0xc0, 0x24, 0x54, + 0xc2, 0x7c, 0xa8, 0x38, 0x11, 0xb3, 0xb2, 0x5d, 0xb4, 0x24, 0x86, 0x8a, 0x84, 0xd4, 0xd9, 0x48, + 0x9b, 0xd0, 0xcc, 0x43, 0x3e, 0x9f, 0x44, 0x4b, 0x85, 0xed, 0x6e, 0x93, 0xf5, 0x23, 0x26, 0x16, + 0xb0, 0xf3, 0xdd, 0x95, 0xd7, 0xd1, 0xb4, 0xa8, 0x23, 0xfc, 0xbd, 0xba, 0xb9, 0xc2, 0x5f, 0x49, + 0x20, 0x67, 0x36, 0x5e, 0x89, 0xf3, 0x77, 0xca, 0x06, 0x5e, 0x29, 0x1f, 0x94, 0xaf, 0x1b, 0x71, + 0xf9, 0x50, 0xdb, 0x18, 0xd7, 0xe9, 0x9b, 0x0e, 0x58, 0x72, 0x88, 0x96, 0x0a, 0xbb, 0x70, 0xa1, + 0x14, 0x1f, 0x9e, 0xd9, 0x8a, 0xff, 0x7a, 0x6a, 0x2b, 0xce, 0xc9, 0xe6, 0x3f, 0xb3, 0xcb, 0xe9, + 0xb5, 0x0b, 0xf1, 0x99, 0x0d, 0xf8, 0x87, 0x49, 0x34, 0x77, 0xcf, 0x8e, 0x59, 0x74, 0xc0, 0xdc, + 0xad, 0xd0, 0x77, 0x59, 0xa4, 0xdf, 0x45, 0x65, 0xfe, 0xbd, 0x23, 0x4b, 0xbf, 0xd2, 0x16, 0x1f, + 0x43, 0xed, 0xec, 0x63, 0xa8, 0xfd, 0x20, 0xfb, 0x18, 0x32, 0x1b, 0xf2, 0xf7, 0x80, 0x9f, 0x2f, + 0x15, 0x5e, 0x8f, 0x91, 0x67, 0x3f, 0x63, 0x8d, 0x02, 0xce, 0x9b, 0xcf, 0xb7, 0x6c, 0xe6, 0x43, + 0xf9, 0xab, 0xa2, 0xf9, 0x00, 0x50, 0x82, 0x02, 0x8b, 0x50, 0x81, 0xea, 0x1f, 0xa3, 0xc5, 0x88, + 0x39, 0xcc, 0x3b, 0x60, 0x9d, 0x7c, 0x29, 0x12, 0xa7, 0xd0, 0x1e, 0xa6, 0x78, 0x41, 0x3a, 0xdf, + 0x2f, 0xec, 0x46, 0xcb, 0x90, 0xe6, 0xb4, 0x83, 0xd0, 0x33, 0x5c, 0xfd, 0x11, 0x5a, 0x88, 0x58, + 0x2f, 0x4c, 0x8a, 0xb9, 0xc5, 0x49, 0xfd, 0x77, 0x98, 0xe2, 0x79, 0xe1, 0x2b, 0xa6, 0x5e, 0x92, + 0xa9, 0xc7, 0x70, 0x42, 0x4f, 0x33, 0xc9, 0xf7, 0x5a, 0x5e, 0x48, 0xd1, 0xc0, 0xe7, 0x5e, 0xc8, + 0xec, 0xbb, 0x64, 0xf2, 0x0d, 0xbe, 0x4b, 0x36, 0xd0, 0x8c, 0xe5, 0xba, 0x11, 0x8b, 0xc5, 0xc8, + 0xad, 0x0a, 0x21, 0x4a, 0x48, 0xc9, 0x42, 0xda, 0x84, 0x66, 0x1e, 0xf3, 0xe6, 0xcb, 0x57, 0x8d, + 0x89, 0xa3, 0x57, 0x8d, 0x89, 0x97, 0xc7, 0x0d, 0xed, 0xe8, 0xb8, 0xa1, 0x3d, 0x3b, 0x69, 0x4c, + 0xbc, 0x38, 0x69, 0x68, 0x47, 0x27, 0x8d, 0x89, 0x1f, 0x4f, 0x1a, 0x13, 0x1f, 0x5d, 0x7a, 0x83, + 0x8f, 0x01, 0xd7, 0xb6, 0xa7, 0xe1, 0x35, 0x2f, 0xff, 0x1e, 0x00, 0x00, 0xff, 0xff, 0x95, 0x1d, + 0x77, 0x00, 0x8b, 0x0f, 0x00, 0x00, } func (m *FileVersion) Marshal() (dAtA []byte, err error) { @@ -752,6 +755,16 @@ func (m *FileInfoTruncated) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x8a } + { + size, err := m.Platform.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintStructs(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 if m.RawBlockSize != 0 { i = encodeVarintStructs(dAtA, i, uint64(m.RawBlockSize)) i-- @@ -1175,12 +1188,12 @@ func (m *ObservedFolder) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - n4, err4 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err4 != nil { - return 0, err4 + n5, err5 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err5 != nil { + return 0, err5 } - i -= n4 - i = encodeVarintStructs(dAtA, i, uint64(n4)) + i -= n5 + i = encodeVarintStructs(dAtA, i, uint64(n5)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -1220,12 +1233,12 @@ func (m *ObservedDevice) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - n5, err5 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err5 != nil { - return 0, err5 + n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err6 != nil { + return 0, err6 } - i -= n5 - i = encodeVarintStructs(dAtA, i, uint64(n5)) + i -= n6 + i = encodeVarintStructs(dAtA, i, uint64(n6)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -1328,6 +1341,8 @@ func (m *FileInfoTruncated) ProtoSize() (n int) { if m.RawBlockSize != 0 { n += 1 + sovStructs(uint64(m.RawBlockSize)) } + l = m.Platform.ProtoSize() + n += 1 + l + sovStructs(uint64(l)) l = len(m.SymlinkTarget) if l > 0 { n += 2 + l + sovStructs(uint64(l)) @@ -2073,6 +2088,39 @@ func (m *FileInfoTruncated) Unmarshal(dAtA []byte) error { break } } + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Platform", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStructs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStructs + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthStructs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Platform.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 17: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SymlinkTarget", wireType) diff --git a/lib/fs/basicfs.go b/lib/fs/basicfs.go index 9ace634a824..a6e2b17e724 100644 --- a/lib/fs/basicfs.go +++ b/lib/fs/basicfs.go @@ -129,14 +129,6 @@ func (f *BasicFilesystem) Chmod(name string, mode FileMode) error { return os.Chmod(name, os.FileMode(mode)) } -func (f *BasicFilesystem) Lchown(name string, uid, gid int) error { - name, err := f.rooted(name) - if err != nil { - return err - } - return os.Lchown(name, uid, gid) -} - func (f *BasicFilesystem) Chtimes(name string, atime time.Time, mtime time.Time) error { name, err := f.rooted(name) if err != nil { diff --git a/lib/fs/basicfs_platformdata_unix.go b/lib/fs/basicfs_platformdata_unix.go new file mode 100644 index 00000000000..f7d56769221 --- /dev/null +++ b/lib/fs/basicfs_platformdata_unix.go @@ -0,0 +1,18 @@ +// Copyright (C) 2022 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +//go:build !windows +// +build !windows + +package fs + +import ( + "github.com/syncthing/syncthing/lib/protocol" +) + +func (f *BasicFilesystem) PlatformData(name string) (protocol.PlatformData, error) { + return unixPlatformData(f, name) +} diff --git a/lib/fs/basicfs_platformdata_windows.go b/lib/fs/basicfs_platformdata_windows.go new file mode 100644 index 00000000000..e1c14804a0b --- /dev/null +++ b/lib/fs/basicfs_platformdata_windows.go @@ -0,0 +1,69 @@ +// Copyright (C) 2022 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +package fs + +import ( + "fmt" + "os/user" + + "github.com/syncthing/syncthing/lib/protocol" + "golang.org/x/sys/windows" +) + +func (f *BasicFilesystem) PlatformData(name string) (protocol.PlatformData, error) { + rootedName, err := f.rooted(name) + if err != nil { + return protocol.PlatformData{}, fmt.Errorf("rooted for %s: %w", name, err) + } + hdl, err := openReadOnlyWithBackupSemantics(rootedName) + if err != nil { + return protocol.PlatformData{}, fmt.Errorf("open %s: %w", rootedName, err) + } + defer windows.Close(hdl) + + // GetSecurityInfo returns an owner SID. + sd, err := windows.GetSecurityInfo(hdl, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION) + if err != nil { + return protocol.PlatformData{}, fmt.Errorf("get security info for %s: %w", rootedName, err) + } + owner, _, err := sd.Owner() + if err != nil { + return protocol.PlatformData{}, fmt.Errorf("get owner for %s: %w", rootedName, err) + } + + // The owner SID might represent a user or a group. We try to look it up + // as both, and set the appropriate fields in the OS data. + pd := &protocol.WindowsData{} + if us, err := user.LookupId(owner.String()); err == nil { + pd.OwnerName = us.Username + } else if gr, err := user.LookupGroupId(owner.String()); err == nil { + pd.OwnerName = gr.Name + pd.OwnerIsGroup = true + } else { + l.Debugf("Failed to resolve owner for %s: %v", rootedName, err) + } + + return protocol.PlatformData{Windows: pd}, nil +} + +func openReadOnlyWithBackupSemantics(path string) (fd windows.Handle, err error) { + // This is windows.Open but simplified to read-only only, and adding + // FILE_FLAG_BACKUP_SEMANTICS which is required to open directories. + if len(path) == 0 { + return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND + } + pathp, err := windows.UTF16PtrFromString(path) + if err != nil { + return windows.InvalidHandle, err + } + var access uint32 = windows.GENERIC_READ + var sharemode uint32 = windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE + var sa *windows.SecurityAttributes + var createmode uint32 = windows.OPEN_EXISTING + var attrs uint32 = windows.FILE_ATTRIBUTE_READONLY | windows.FILE_FLAG_BACKUP_SEMANTICS + return windows.CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0) +} diff --git a/lib/fs/basicfs_test.go b/lib/fs/basicfs_test.go index 04db3bf4b5e..261167f792d 100644 --- a/lib/fs/basicfs_test.go +++ b/lib/fs/basicfs_test.go @@ -11,6 +11,7 @@ import ( "path/filepath" "runtime" "sort" + "strconv" "strings" "testing" "time" @@ -84,7 +85,7 @@ func TestChownFile(t *testing.T) { newUID := 1000 + rand.Intn(30000) newGID := 1000 + rand.Intn(30000) - if err := fs.Lchown("file", newUID, newGID); err != nil { + if err := fs.Lchown("file", strconv.Itoa(newUID), strconv.Itoa(newGID)); err != nil { t.Error("Unexpected error:", err) } diff --git a/lib/fs/basicfs_unix.go b/lib/fs/basicfs_unix.go index 3d6a9bfd7e8..9f7f65831e9 100644 --- a/lib/fs/basicfs_unix.go +++ b/lib/fs/basicfs_unix.go @@ -12,6 +12,7 @@ package fs import ( "os" "path/filepath" + "strconv" "strings" ) @@ -57,6 +58,22 @@ func (f *BasicFilesystem) Roots() ([]string, error) { return []string{"/"}, nil } +func (f *BasicFilesystem) Lchown(name, uid, gid string) error { + name, err := f.rooted(name) + if err != nil { + return err + } + nuid, err := strconv.Atoi(uid) + if err != nil { + return err + } + ngid, err := strconv.Atoi(gid) + if err != nil { + return err + } + return os.Lchown(name, nuid, ngid) +} + // unrootedChecked returns the path relative to the folder root (same as // unrooted) or an error if the given path is not a subpath and handles the // special case when the given path is the folder root without a trailing diff --git a/lib/fs/basicfs_windows.go b/lib/fs/basicfs_windows.go index d23f03863b7..83445285a2a 100644 --- a/lib/fs/basicfs_windows.go +++ b/lib/fs/basicfs_windows.go @@ -17,6 +17,8 @@ import ( "strings" "syscall" "unsafe" + + "golang.org/x/sys/windows" ) var errNotSupported = errors.New("symlinks not supported") @@ -152,6 +154,42 @@ func (f *BasicFilesystem) Roots() ([]string, error) { return drives, nil } +func (f *BasicFilesystem) Lchown(name, uid, gid string) error { + name, err := f.rooted(name) + if err != nil { + return err + } + + hdl, err := windows.Open(name, windows.O_WRONLY, 0) + if err != nil { + return err + } + defer windows.Close(hdl) + + // Depending on whether we got an uid or a gid, we need to set the + // appropriate flag and parse the corresponding SID. The one we're not + // setting remains nil, which is what we want in the call to + // SetSecurityInfo. + + var si windows.SECURITY_INFORMATION + var ownerSID, groupSID *syscall.SID + if uid != "" { + ownerSID, err = syscall.StringToSid(uid) + if err == nil { + si |= windows.OWNER_SECURITY_INFORMATION + } + } else if gid != "" { + groupSID, err = syscall.StringToSid(uid) + if err == nil { + si |= windows.GROUP_SECURITY_INFORMATION + } + } else { + return errors.New("neither uid nor gid specified") + } + + return windows.SetSecurityInfo(hdl, windows.SE_FILE_OBJECT, si, (*windows.SID)(ownerSID), (*windows.SID)(groupSID), nil, nil) +} + // unrootedChecked returns the path relative to the folder root (same as // unrooted) or an error if the given path is not a subpath and handles the // special case when the given path is the folder root without a trailing diff --git a/lib/fs/casefs.go b/lib/fs/casefs.go index 71bef00d861..929aad12039 100644 --- a/lib/fs/casefs.go +++ b/lib/fs/casefs.go @@ -153,7 +153,7 @@ func (f *caseFilesystem) Chmod(name string, mode FileMode) error { return f.Filesystem.Chmod(name, mode) } -func (f *caseFilesystem) Lchown(name string, uid, gid int) error { +func (f *caseFilesystem) Lchown(name, uid, gid string) error { if err := f.checkCase(name); err != nil { return err } diff --git a/lib/fs/errorfs.go b/lib/fs/errorfs.go index 1c9965af5cd..06564ba3d08 100644 --- a/lib/fs/errorfs.go +++ b/lib/fs/errorfs.go @@ -9,6 +9,8 @@ package fs import ( "context" "time" + + "github.com/syncthing/syncthing/lib/protocol" ) type errorFilesystem struct { @@ -18,7 +20,7 @@ type errorFilesystem struct { } func (fs *errorFilesystem) Chmod(name string, mode FileMode) error { return fs.err } -func (fs *errorFilesystem) Lchown(name string, uid, gid int) error { return fs.err } +func (fs *errorFilesystem) Lchown(name, uid, gid string) error { return fs.err } func (fs *errorFilesystem) Chtimes(name string, atime time.Time, mtime time.Time) error { return fs.err } @@ -52,6 +54,9 @@ func (fs *errorFilesystem) SameFile(fi1, fi2 FileInfo) bool { return false } func (fs *errorFilesystem) Watch(path string, ignore Matcher, ctx context.Context, ignorePerms bool) (<-chan Event, <-chan error, error) { return nil, nil, fs.err } +func (fs *errorFilesystem) PlatformData(name string) (protocol.PlatformData, error) { + return protocol.PlatformData{}, fs.err +} func (fs *errorFilesystem) underlying() (Filesystem, bool) { return nil, false diff --git a/lib/fs/fakefs.go b/lib/fs/fakefs.go index 8e66f526ffb..a33985cb810 100644 --- a/lib/fs/fakefs.go +++ b/lib/fs/fakefs.go @@ -21,6 +21,8 @@ import ( "sync" "testing" "time" + + "github.com/syncthing/syncthing/lib/protocol" ) // see readShortAt() @@ -29,19 +31,19 @@ const randomBlockShift = 14 // 128k // fakeFS is a fake filesystem for testing and benchmarking. It has the // following properties: // -// - File metadata is kept in RAM. Specifically, we remember which files and -// directories exist, their dates, permissions and sizes. Symlinks are -// not supported. +// - File metadata is kept in RAM. Specifically, we remember which files and +// directories exist, their dates, permissions and sizes. Symlinks are +// not supported. // -// - File contents are generated pseudorandomly with just the file name as -// seed. Writes are discarded, other than having the effect of increasing -// the file size. If you only write data that you've read from a file with -// the same name on a different fakeFS, you'll never know the difference... +// - File contents are generated pseudorandomly with just the file name as +// seed. Writes are discarded, other than having the effect of increasing +// the file size. If you only write data that you've read from a file with +// the same name on a different fakeFS, you'll never know the difference... // // - We totally ignore permissions - pretend you are root. // -// - The root path can contain URL query-style parameters that pre populate -// the filesystem at creation with a certain amount of random data: +// - The root path can contain URL query-style parameters that pre populate +// the filesystem at creation with a certain amount of random data: // // files=n to generate n random files (default 0) // maxsize=n to generate files up to a total of n MiB (default 0) @@ -51,7 +53,6 @@ const randomBlockShift = 14 // 128k // latency=d to set the amount of time each "disk" operation takes, where d is time.ParseDuration format // // - Two fakeFS:s pointing at the same root path see the same files. -// type fakeFS struct { counters fakeFSCounters uri string @@ -220,7 +221,7 @@ func (fs *fakeFS) Chmod(name string, mode FileMode) error { return nil } -func (fs *fakeFS) Lchown(name string, uid, gid int) error { +func (fs *fakeFS) Lchown(name, uid, gid string) error { fs.mut.Lock() defer fs.mut.Unlock() fs.counters.Lchown++ @@ -229,8 +230,8 @@ func (fs *fakeFS) Lchown(name string, uid, gid int) error { if entry == nil { return os.ErrNotExist } - entry.uid = uid - entry.gid = gid + entry.uid, _ = strconv.Atoi(uid) + entry.gid, _ = strconv.Atoi(gid) return nil } @@ -656,6 +657,10 @@ func (fs *fakeFS) SameFile(fi1, fi2 FileInfo) bool { return ok && fi1.ModTime().Equal(fi2.ModTime()) && fi1.Mode() == fi2.Mode() && fi1.IsDir() == fi2.IsDir() && fi1.IsRegular() == fi2.IsRegular() && fi1.IsSymlink() == fi2.IsSymlink() && fi1.Owner() == fi2.Owner() && fi1.Group() == fi2.Group() } +func (fs *fakeFS) PlatformData(name string) (protocol.PlatformData, error) { + return unixPlatformData(fs, name) +} + func (fs *fakeFS) underlying() (Filesystem, bool) { return nil, false } diff --git a/lib/fs/fakefs_test.go b/lib/fs/fakefs_test.go index 3ace32470af..04b3ecbad80 100644 --- a/lib/fs/fakefs_test.go +++ b/lib/fs/fakefs_test.go @@ -119,7 +119,7 @@ func TestFakeFS(t *testing.T) { } // Chown - if err := fs.Lchown("dira", 1234, 5678); err != nil { + if err := fs.Lchown("dira", "1234", "5678"); err != nil { t.Fatal(err) } if info, err := fs.Lstat("dira"); err != nil { diff --git a/lib/fs/filesystem.go b/lib/fs/filesystem.go index d834f9950a4..0653b128a48 100644 --- a/lib/fs/filesystem.go +++ b/lib/fs/filesystem.go @@ -14,6 +14,8 @@ import ( "path/filepath" "strings" "time" + + "github.com/syncthing/syncthing/lib/protocol" ) type filesystemWrapperType int32 @@ -30,7 +32,7 @@ const ( // The Filesystem interface abstracts access to the file system. type Filesystem interface { Chmod(name string, mode FileMode) error - Lchown(name string, uid, gid int) error + Lchown(name string, uid, gid string) error // uid/gid as strings; numeric on POSIX, SID on Windows, like in os/user package Chtimes(name string, atime time.Time, mtime time.Time) error Create(name string) (File, error) CreateSymlink(target, name string) error @@ -60,6 +62,7 @@ type Filesystem interface { URI() string Options() []Option SameFile(fi1, fi2 FileInfo) bool + PlatformData(name string) (protocol.PlatformData, error) // Used for unwrapping things underlying() (Filesystem, bool) diff --git a/lib/fs/mtimefs.go b/lib/fs/mtimefs.go index 832b872c934..2dfcbfe6ba3 100644 --- a/lib/fs/mtimefs.go +++ b/lib/fs/mtimefs.go @@ -59,7 +59,7 @@ func (o *optionMtime) apply(fs Filesystem) Filesystem { return f } -func (_ *optionMtime) String() string { +func (*optionMtime) String() string { return "mtime" } diff --git a/lib/fs/platform_common.go b/lib/fs/platform_common.go new file mode 100644 index 00000000000..aea876c7db9 --- /dev/null +++ b/lib/fs/platform_common.go @@ -0,0 +1,55 @@ +// Copyright (C) 2022 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +package fs + +import ( + "os/user" + "strconv" + + "github.com/syncthing/syncthing/lib/protocol" +) + +// unixPlatformData is used on all platforms, because apart from being the +// implementation for BasicFilesystem on Unixes it's also the implementation +// in fakeFS. +func unixPlatformData(fs Filesystem, name string) (protocol.PlatformData, error) { + stat, err := fs.Lstat(name) + if err != nil { + return protocol.PlatformData{}, err + } + + ownerUID := stat.Owner() + ownerName := "" + if u, err := user.LookupId(strconv.Itoa(ownerUID)); err == nil && u.Username != "" { + ownerName = u.Username + } else if ownerUID == 0 { + // We couldn't look up a name, but UID zero should be "root". This + // fixup works around the (unlikely) situation where the ownership + // is 0:0 but we can't look up a name for either uid zero or gid + // zero. If that were the case we'd return a zero PlatformData which + // wouldn't get serialized over the wire and the other side would + // assume a lack of ownership info... + ownerName = "root" + } + + groupID := stat.Group() + groupName := "" + if g, err := user.LookupGroupId(strconv.Itoa(groupID)); err == nil && g.Name != "" { + groupName = g.Name + } else if groupID == 0 { + groupName = "root" + } + + return protocol.PlatformData{ + Unix: &protocol.UnixData{ + OwnerName: ownerName, + GroupName: groupName, + UID: ownerUID, + GID: groupID, + }, + }, nil +} diff --git a/lib/model/folder.go b/lib/model/folder.go index 0091674caa6..41d26a4dcad 100644 --- a/lib/model/folder.go +++ b/lib/model/folder.go @@ -602,7 +602,13 @@ func (b *scanBatch) Update(fi protocol.FileInfo, snap *db.Snapshot) bool { b.Remove(fi.Name) return true } - case gf.IsEquivalentOptional(fi, b.f.modTimeWindow, false, false, protocol.FlagLocalReceiveOnly): + case gf.IsEquivalentOptional(fi, protocol.FileInfoComparison{ + ModTimeWindow: b.f.modTimeWindow, + IgnorePerms: b.f.IgnorePerms, + IgnoreBlocks: true, + IgnoreFlags: protocol.FlagLocalReceiveOnly, + IgnoreOwnership: !b.f.SyncOwnership, + }): // What we have locally is equivalent to the global file. l.Debugf("%v scanning: Merging identical locally changed item with global", b.f, fi) fi = gf @@ -632,6 +638,7 @@ func (f *folder) scanSubdirsChangedAndNew(subDirs []string, batch *scanBatch) (i CurrentFiler: cFiler{snap}, Filesystem: f.mtimefs, IgnorePerms: f.IgnorePerms, + IgnoreOwnership: !f.SyncOwnership, AutoNormalize: f.AutoNormalize, Hashers: f.model.numHashers(f.ID), ShortID: f.shortID, diff --git a/lib/model/folder_recvonly.go b/lib/model/folder_recvonly.go index 827fbe5d863..41f2b24ea57 100644 --- a/lib/model/folder_recvonly.go +++ b/lib/model/folder_recvonly.go @@ -126,7 +126,11 @@ func (f *receiveOnlyFolder) revert() error { } fi.SetDeleted(f.shortID) fi.Version = protocol.Vector{} // if this file ever resurfaces anywhere we want our delete to be strictly older - case gf.IsEquivalentOptional(fi, f.modTimeWindow, false, false, protocol.FlagLocalReceiveOnly): + case gf.IsEquivalentOptional(fi, protocol.FileInfoComparison{ + ModTimeWindow: f.modTimeWindow, + IgnoreFlags: protocol.FlagLocalReceiveOnly, + IgnoreOwnership: !f.SyncOwnership, + }): // What we have locally is equivalent to the global file. fi = gf default: diff --git a/lib/model/folder_sendonly.go b/lib/model/folder_sendonly.go index 9b6104fffaf..7ab6c6dad6f 100644 --- a/lib/model/folder_sendonly.go +++ b/lib/model/folder_sendonly.go @@ -72,7 +72,11 @@ func (f *sendOnlyFolder) pull() (bool, error) { return true } - if !file.IsEquivalentOptional(curFile, f.modTimeWindow, f.IgnorePerms, false, 0) { + if !file.IsEquivalentOptional(curFile, protocol.FileInfoComparison{ + ModTimeWindow: f.modTimeWindow, + IgnorePerms: f.IgnorePerms, + IgnoreOwnership: !f.SyncOwnership, + }) { return true } diff --git a/lib/model/folder_sendrecv.go b/lib/model/folder_sendrecv.go index e8f0af524a0..bc3f45c900b 100644 --- a/lib/model/folder_sendrecv.go +++ b/lib/model/folder_sendrecv.go @@ -13,6 +13,7 @@ import ( "path/filepath" "runtime" "sort" + "strconv" "strings" "time" @@ -627,8 +628,8 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo, snap *db.Snapshot, return err } - // Copy the parent owner and group, if we are supposed to do that. - if err := f.maybeCopyOwner(path); err != nil { + // Adjust the ownership, if we are supposed to do that. + if err := f.maybeAdjustOwnership(&file, path); err != nil { return err } @@ -754,7 +755,7 @@ func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo, snap *db.Snaps if err := f.mtimefs.CreateSymlink(file.SymlinkTarget, path); err != nil { return err } - return f.maybeCopyOwner(path) + return f.maybeAdjustOwnership(&file, path) } if err = f.inWritableDir(createLink, file.Name); err == nil { @@ -989,7 +990,13 @@ func (f *sendReceiveFolder) renameFile(cur, source, target protocol.FileInfo, sn default: var fi protocol.FileInfo if fi, err = scanner.CreateFileInfo(stat, target.Name, f.mtimefs); err == nil { - if !fi.IsEquivalentOptional(curTarget, f.modTimeWindow, f.IgnorePerms, true, protocol.LocalAllFlags) { + if !fi.IsEquivalentOptional(curTarget, protocol.FileInfoComparison{ + ModTimeWindow: f.modTimeWindow, + IgnorePerms: f.IgnorePerms, + IgnoreBlocks: true, + IgnoreFlags: protocol.LocalAllFlags, + IgnoreOwnership: !f.SyncOwnership, + }) { // Target changed scanChan <- target.Name err = errModified @@ -1227,6 +1234,11 @@ func (f *sendReceiveFolder) shortcutFile(file protocol.FileInfo, dbUpdateChan ch } } + if err := f.maybeAdjustOwnership(&file, file.Name); err != nil { + f.newPullError(file.Name, err) + return + } + // Still need to re-write the trailer with the new encrypted fileinfo. if f.Type == config.FolderTypeReceiveEncrypted { err = inWritableDir(func(path string) error { @@ -1592,8 +1604,8 @@ func (f *sendReceiveFolder) performFinish(file, curFile protocol.FileInfo, hasCu } } - // Copy the parent owner and group, if we are supposed to do that. - if err := f.maybeCopyOwner(tempName); err != nil { + // Set ownership based on file metadata or parent, maybe. + if err := f.maybeAdjustOwnership(&file, tempName); err != nil { return err } @@ -1972,7 +1984,13 @@ func (f *sendReceiveFolder) deleteDirOnDiskHandleChildren(dir string, snap *db.S hasToBeScanned = true return nil } - if !cf.IsEquivalentOptional(diskFile, f.modTimeWindow, f.IgnorePerms, true, protocol.LocalAllFlags) { + if !cf.IsEquivalentOptional(diskFile, protocol.FileInfoComparison{ + ModTimeWindow: f.modTimeWindow, + IgnorePerms: f.IgnorePerms, + IgnoreBlocks: true, + IgnoreFlags: protocol.LocalAllFlags, + IgnoreOwnership: !f.SyncOwnership, + }) { // File on disk changed compared to what we have in db // -> schedule scan. scanChan <- path @@ -2041,7 +2059,13 @@ func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, ite return errors.Wrap(err, "comparing item on disk to db") } - if !statItem.IsEquivalentOptional(item, f.modTimeWindow, f.IgnorePerms, true, protocol.LocalAllFlags) { + if !statItem.IsEquivalentOptional(item, protocol.FileInfoComparison{ + ModTimeWindow: f.modTimeWindow, + IgnorePerms: f.IgnorePerms, + IgnoreBlocks: true, + IgnoreFlags: protocol.LocalAllFlags, + IgnoreOwnership: !f.SyncOwnership, + }) { return errModified } @@ -2074,11 +2098,23 @@ func (f *sendReceiveFolder) checkToBeDeleted(file, cur protocol.FileInfo, hasCur return f.scanIfItemChanged(file.Name, stat, cur, hasCur, scanChan) } -func (f *sendReceiveFolder) maybeCopyOwner(path string) error { - if !f.CopyOwnershipFromParent { - // Not supposed to do anything. - return nil +func (f *sendReceiveFolder) maybeAdjustOwnership(file *protocol.FileInfo, name string) error { + if f.SyncOwnership { + // Set ownership based on file metadata. + if err := f.syncOwnership(file, name); err != nil { + return err + } + } else if f.CopyOwnershipFromParent { + // Copy the parent owner and group. + if err := f.copyOwnershipFromParent(name); err != nil { + return err + } } + // Nothing to do + return nil +} + +func (f *sendReceiveFolder) copyOwnershipFromParent(path string) error { if runtime.GOOS == "windows" { // Can't do anything. return nil @@ -2088,7 +2124,7 @@ func (f *sendReceiveFolder) maybeCopyOwner(path string) error { if err != nil { return errors.Wrap(err, "copy owner from parent") } - if err := f.mtimefs.Lchown(path, info.Owner(), info.Group()); err != nil { + if err := f.mtimefs.Lchown(path, strconv.Itoa(info.Owner()), strconv.Itoa(info.Group())); err != nil { return errors.Wrap(err, "copy owner from parent") } return nil diff --git a/lib/model/folder_sendrecv_test.go b/lib/model/folder_sendrecv_test.go index 4793f74dd5b..608b5a87da2 100644 --- a/lib/model/folder_sendrecv_test.go +++ b/lib/model/folder_sendrecv_test.go @@ -16,6 +16,7 @@ import ( "os" "path/filepath" "runtime" + "strconv" "strings" "testing" "time" @@ -811,7 +812,7 @@ func TestCopyOwner(t *testing.T) { // Create a parent dir with a certain owner/group. f.mtimefs.Mkdir("foo", 0755) - f.mtimefs.Lchown("foo", expOwner, expGroup) + f.mtimefs.Lchown("foo", strconv.Itoa(expOwner), strconv.Itoa(expGroup)) dir := protocol.FileInfo{ Name: "foo/bar", diff --git a/lib/model/folder_sendrecv_unix.go b/lib/model/folder_sendrecv_unix.go new file mode 100644 index 00000000000..978159094f3 --- /dev/null +++ b/lib/model/folder_sendrecv_unix.go @@ -0,0 +1,45 @@ +// Copyright (C) 2022 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +//go:build !windows +// +build !windows + +package model + +import ( + "os/user" + "strconv" + + "github.com/syncthing/syncthing/lib/protocol" +) + +func (f *sendReceiveFolder) syncOwnership(file *protocol.FileInfo, path string) error { + if file.Platform.Unix == nil { + // No owner data, nothing to do + return nil + } + + // Try to look up the user and group by name, defaulting to the + // numerical UID and GID if there is no match. + + uid := strconv.Itoa(file.Platform.Unix.UID) + if file.Platform.Unix.OwnerName != "" { + us, err := user.Lookup(file.Platform.Unix.OwnerName) + if err == nil && us.Uid != "" { + uid = us.Uid + } + } + + gid := strconv.Itoa(file.Platform.Unix.GID) + if file.Platform.Unix.GroupName != "" { + gr, err := user.LookupGroup(file.Platform.Unix.GroupName) + if err == nil && gr.Gid != "" { + gid = gr.Gid + } + } + + return f.mtimefs.Lchown(path, uid, gid) +} diff --git a/lib/model/folder_sendrecv_windows.go b/lib/model/folder_sendrecv_windows.go new file mode 100644 index 00000000000..28ebe01d14c --- /dev/null +++ b/lib/model/folder_sendrecv_windows.go @@ -0,0 +1,82 @@ +// Copyright (C) 2022 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +package model + +import ( + "errors" + "os/user" + "strings" + + "github.com/syncthing/syncthing/lib/protocol" +) + +func (f *sendReceiveFolder) syncOwnership(file *protocol.FileInfo, path string) error { + if file.Platform.Windows == nil || file.Platform.Windows.OwnerName == "" { + // No owner data, nothing to do + return nil + } + + l.Debugln("Owner name for %s is %s (group=%v)", path, file.Platform.Windows.OwnerName, file.Platform.Windows.OwnerIsGroup) + usid, gsid, err := lookupUserAndGroup(file.Platform.Windows.OwnerName, file.Platform.Windows.OwnerIsGroup) + if err != nil { + return err + } + + l.Debugln("Owner for %s resolved to uid=%q gid=%q", path, usid, gsid) + return f.mtimefs.Lchown(path, usid, gsid) +} + +func lookupUserAndGroup(name string, group bool) (string, string, error) { + // Look up either the the user or the group, returning the other kind as + // blank. This might seem an odd maneuver, but it matches what Chown + // wants as input and hides the ugly nested if:s down here. + + if group { + gr, err := lookupWithoutDomain(name, func(name string) (string, error) { + gr, err := user.LookupGroup(name) + if err == nil { + return gr.Gid, nil + } + return "", err + }) + if err != nil { + return "", "", err + } + return "", gr, nil + } + + us, err := lookupWithoutDomain(name, func(name string) (string, error) { + us, err := user.Lookup(name) + if err == nil { + return us.Uid, nil + } + return "", err + }) + if err != nil { + return "", "", err + } + return us, "", nil +} + +func lookupWithoutDomain(name string, lookup func(s string) (string, error)) (string, error) { + // Try to look up the user by name. The username will be either a plain + // username or a qualified DOMAIN\user. We'll first try to look up + // whatever we got, if that fails, we'll try again with just the user + // part without domain. + + v, err := lookup(name) + if err == nil { + return v, nil + } + parts := strings.Split(name, `\`) + if len(parts) == 2 { + if v, err := lookup(parts[1]); err == nil { + return v, nil + } + } + return "", errors.New("lookup failed") +} diff --git a/lib/protocol/bep.pb.go b/lib/protocol/bep.pb.go index 17843d53f9f..148da5be710 100644 --- a/lib/protocol/bep.pb.go +++ b/lib/protocol/bep.pb.go @@ -505,6 +505,7 @@ type FileInfo struct { Permissions uint32 `protobuf:"varint,4,opt,name=permissions,proto3" json:"permissions" xml:"permissions"` ModifiedNs int `protobuf:"varint,11,opt,name=modified_ns,json=modifiedNs,proto3,casttype=int" json:"modifiedNs" xml:"modifiedNs"` RawBlockSize int `protobuf:"varint,13,opt,name=block_size,json=blockSize,proto3,casttype=int" json:"blockSize" xml:"blockSize"` + Platform PlatformData `protobuf:"bytes,14,opt,name=platform,proto3" json:"platform" xml:"platform"` // The local_flags fields stores flags that are relevant to the local // host only. It is not part of the protocol, doesn't get sent or // received (we make sure to zero it), nonetheless we need it on our @@ -664,6 +665,128 @@ func (m *Counter) XXX_DiscardUnknown() { var xxx_messageInfo_Counter proto.InternalMessageInfo +type PlatformData struct { + Unix *UnixData `protobuf:"bytes,1,opt,name=unix,proto3" json:"unix" xml:"unix"` + Windows *WindowsData `protobuf:"bytes,2,opt,name=windows,proto3" json:"windows" xml:"windows"` +} + +func (m *PlatformData) Reset() { *m = PlatformData{} } +func (m *PlatformData) String() string { return proto.CompactTextString(m) } +func (*PlatformData) ProtoMessage() {} +func (*PlatformData) Descriptor() ([]byte, []int) { + return fileDescriptor_311ef540e10d9705, []int{11} +} +func (m *PlatformData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PlatformData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PlatformData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PlatformData) XXX_Merge(src proto.Message) { + xxx_messageInfo_PlatformData.Merge(m, src) +} +func (m *PlatformData) XXX_Size() int { + return m.ProtoSize() +} +func (m *PlatformData) XXX_DiscardUnknown() { + xxx_messageInfo_PlatformData.DiscardUnknown(m) +} + +var xxx_messageInfo_PlatformData proto.InternalMessageInfo + +type UnixData struct { + // The owner name and group name are set when known (i.e., could be + // resolved on the source device), while the UID and GID are always set + // as they come directly from the stat() call. + OwnerName string `protobuf:"bytes,1,opt,name=owner_name,json=ownerName,proto3" json:"ownerName" xml:"ownerName"` + GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"groupName" xml:"groupName"` + UID int `protobuf:"varint,3,opt,name=uid,proto3,casttype=int" json:"uid" xml:"uid"` + GID int `protobuf:"varint,4,opt,name=gid,proto3,casttype=int" json:"gid" xml:"gid"` +} + +func (m *UnixData) Reset() { *m = UnixData{} } +func (m *UnixData) String() string { return proto.CompactTextString(m) } +func (*UnixData) ProtoMessage() {} +func (*UnixData) Descriptor() ([]byte, []int) { + return fileDescriptor_311ef540e10d9705, []int{12} +} +func (m *UnixData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UnixData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UnixData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UnixData) XXX_Merge(src proto.Message) { + xxx_messageInfo_UnixData.Merge(m, src) +} +func (m *UnixData) XXX_Size() int { + return m.ProtoSize() +} +func (m *UnixData) XXX_DiscardUnknown() { + xxx_messageInfo_UnixData.DiscardUnknown(m) +} + +var xxx_messageInfo_UnixData proto.InternalMessageInfo + +type WindowsData struct { + // Windows file objects have a single owner, which may be a user or a + // group. We keep the name of that account, and a flag to indicate what + // type it is. + OwnerName string `protobuf:"bytes,1,opt,name=owner_name,json=ownerName,proto3" json:"ownerName" xml:"ownerName"` + OwnerIsGroup bool `protobuf:"varint,2,opt,name=owner_is_group,json=ownerIsGroup,proto3" json:"ownerIsGroup" xml:"ownerIsGroup"` +} + +func (m *WindowsData) Reset() { *m = WindowsData{} } +func (m *WindowsData) String() string { return proto.CompactTextString(m) } +func (*WindowsData) ProtoMessage() {} +func (*WindowsData) Descriptor() ([]byte, []int) { + return fileDescriptor_311ef540e10d9705, []int{13} +} +func (m *WindowsData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WindowsData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WindowsData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WindowsData) XXX_Merge(src proto.Message) { + xxx_messageInfo_WindowsData.Merge(m, src) +} +func (m *WindowsData) XXX_Size() int { + return m.ProtoSize() +} +func (m *WindowsData) XXX_DiscardUnknown() { + xxx_messageInfo_WindowsData.DiscardUnknown(m) +} + +var xxx_messageInfo_WindowsData proto.InternalMessageInfo + type Request struct { ID int `protobuf:"varint,1,opt,name=id,proto3,casttype=int" json:"id" xml:"id"` Folder string `protobuf:"bytes,2,opt,name=folder,proto3" json:"folder" xml:"folder"` @@ -680,7 +803,7 @@ func (m *Request) Reset() { *m = Request{} } func (m *Request) String() string { return proto.CompactTextString(m) } func (*Request) ProtoMessage() {} func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_311ef540e10d9705, []int{11} + return fileDescriptor_311ef540e10d9705, []int{14} } func (m *Request) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -719,7 +842,7 @@ func (m *Response) Reset() { *m = Response{} } func (m *Response) String() string { return proto.CompactTextString(m) } func (*Response) ProtoMessage() {} func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_311ef540e10d9705, []int{12} + return fileDescriptor_311ef540e10d9705, []int{15} } func (m *Response) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -757,7 +880,7 @@ func (m *DownloadProgress) Reset() { *m = DownloadProgress{} } func (m *DownloadProgress) String() string { return proto.CompactTextString(m) } func (*DownloadProgress) ProtoMessage() {} func (*DownloadProgress) Descriptor() ([]byte, []int) { - return fileDescriptor_311ef540e10d9705, []int{13} + return fileDescriptor_311ef540e10d9705, []int{16} } func (m *DownloadProgress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -798,7 +921,7 @@ func (m *FileDownloadProgressUpdate) Reset() { *m = FileDownloadProgress func (m *FileDownloadProgressUpdate) String() string { return proto.CompactTextString(m) } func (*FileDownloadProgressUpdate) ProtoMessage() {} func (*FileDownloadProgressUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_311ef540e10d9705, []int{14} + return fileDescriptor_311ef540e10d9705, []int{17} } func (m *FileDownloadProgressUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -834,7 +957,7 @@ func (m *Ping) Reset() { *m = Ping{} } func (m *Ping) String() string { return proto.CompactTextString(m) } func (*Ping) ProtoMessage() {} func (*Ping) Descriptor() ([]byte, []int) { - return fileDescriptor_311ef540e10d9705, []int{15} + return fileDescriptor_311ef540e10d9705, []int{18} } func (m *Ping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -871,7 +994,7 @@ func (m *Close) Reset() { *m = Close{} } func (m *Close) String() string { return proto.CompactTextString(m) } func (*Close) ProtoMessage() {} func (*Close) Descriptor() ([]byte, []int) { - return fileDescriptor_311ef540e10d9705, []int{16} + return fileDescriptor_311ef540e10d9705, []int{19} } func (m *Close) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -918,6 +1041,9 @@ func init() { proto.RegisterType((*BlockInfo)(nil), "protocol.BlockInfo") proto.RegisterType((*Vector)(nil), "protocol.Vector") proto.RegisterType((*Counter)(nil), "protocol.Counter") + proto.RegisterType((*PlatformData)(nil), "protocol.PlatformData") + proto.RegisterType((*UnixData)(nil), "protocol.UnixData") + proto.RegisterType((*WindowsData)(nil), "protocol.WindowsData") proto.RegisterType((*Request)(nil), "protocol.Request") proto.RegisterType((*Response)(nil), "protocol.Response") proto.RegisterType((*DownloadProgress)(nil), "protocol.DownloadProgress") @@ -929,175 +1055,190 @@ func init() { func init() { proto.RegisterFile("lib/protocol/bep.proto", fileDescriptor_311ef540e10d9705) } var fileDescriptor_311ef540e10d9705 = []byte{ - // 2681 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0x4d, 0x6c, 0x1b, 0xc7, - 0xf5, 0xd7, 0x92, 0x94, 0x44, 0x8d, 0x24, 0x87, 0x1a, 0x7f, 0x6d, 0x68, 0x9b, 0xcb, 0xff, 0xc4, - 0xf9, 0x57, 0x51, 0x1a, 0x39, 0x51, 0x92, 0x36, 0x4d, 0x52, 0x07, 0xfc, 0x92, 0xc4, 0x44, 0x22, - 0xd9, 0x21, 0xed, 0xd4, 0x46, 0x0b, 0x62, 0xc5, 0x1d, 0x51, 0x0b, 0x2f, 0x77, 0xd9, 0x5d, 0x4a, - 0xb6, 0x82, 0x5e, 0xda, 0x5e, 0x02, 0x1e, 0x8a, 0x22, 0xa7, 0xa2, 0x28, 0xd1, 0xa0, 0x97, 0xde, - 0x0a, 0xf4, 0xd0, 0x4b, 0x4e, 0x3d, 0xe6, 0x68, 0x04, 0x28, 0x50, 0xf4, 0xb0, 0x80, 0xed, 0x4b, - 0xcb, 0x23, 0x8f, 0x3d, 0x15, 0xf3, 0xb1, 0xbb, 0xb3, 0xa2, 0x14, 0xc8, 0xc9, 0xa1, 0xb7, 0x7d, - 0xbf, 0xf7, 0x7b, 0x6f, 0x86, 0x6f, 0xde, 0x7b, 0xf3, 0x76, 0x09, 0xae, 0x58, 0xe6, 0xde, 0xad, - 0xbe, 0xeb, 0x0c, 0x9c, 0x8e, 0x63, 0xdd, 0xda, 0x23, 0xfd, 0x75, 0x26, 0xc0, 0x74, 0x80, 0x65, - 0x17, 0xc8, 0xa3, 0x01, 0x07, 0xb3, 0x2f, 0xb9, 0xa4, 0xef, 0x78, 0x9c, 0xbe, 0x77, 0xb8, 0x7f, - 0xab, 0xeb, 0x74, 0x1d, 0x26, 0xb0, 0x27, 0x4e, 0x42, 0x4f, 0x15, 0x30, 0xbb, 0x4d, 0x2c, 0xcb, - 0x81, 0x25, 0xb0, 0x68, 0x90, 0x23, 0xb3, 0x43, 0xda, 0xb6, 0xde, 0x23, 0xaa, 0x92, 0x57, 0x56, - 0x17, 0x8a, 0x68, 0xec, 0x6b, 0x80, 0xc3, 0x35, 0xbd, 0x47, 0x26, 0xbe, 0x96, 0x79, 0xd4, 0xb3, - 0xde, 0x45, 0x11, 0x84, 0xb0, 0xa4, 0xa7, 0x4e, 0x3a, 0x96, 0x49, 0xec, 0x01, 0x77, 0x92, 0x88, - 0x9c, 0x70, 0x38, 0xe6, 0x24, 0x82, 0x10, 0x96, 0xf4, 0xb0, 0x0e, 0x2e, 0x08, 0x27, 0x47, 0xc4, - 0xf5, 0x4c, 0xc7, 0x56, 0x93, 0xcc, 0xcf, 0xea, 0xd8, 0xd7, 0x96, 0xb9, 0xe6, 0x2e, 0x57, 0x4c, - 0x7c, 0xed, 0xa2, 0xe4, 0x4a, 0xa0, 0x08, 0xc7, 0x59, 0xe8, 0x2f, 0x0a, 0x98, 0xdb, 0x26, 0xba, - 0x41, 0x5c, 0x58, 0x00, 0xa9, 0xc1, 0x71, 0x9f, 0xff, 0xbc, 0x0b, 0x1b, 0x97, 0xd7, 0x83, 0xc0, - 0xad, 0xef, 0x12, 0xcf, 0xd3, 0xbb, 0xa4, 0x75, 0xdc, 0x27, 0xc5, 0x2b, 0x63, 0x5f, 0x63, 0xb4, - 0x89, 0xaf, 0x01, 0xe6, 0x9f, 0x0a, 0x08, 0x33, 0x0c, 0x1a, 0x60, 0xb1, 0xe3, 0xf4, 0xfa, 0x2e, - 0xf1, 0xd8, 0xde, 0x12, 0xcc, 0xd3, 0xf5, 0x29, 0x4f, 0xa5, 0x88, 0x53, 0xbc, 0x39, 0xf6, 0x35, - 0xd9, 0x68, 0xe2, 0x6b, 0x2b, 0x7c, 0xdf, 0x11, 0x86, 0xb0, 0xcc, 0x40, 0x3f, 0x01, 0xcb, 0x25, - 0xeb, 0xd0, 0x1b, 0x10, 0xb7, 0xe4, 0xd8, 0xfb, 0x66, 0x17, 0x7e, 0x04, 0xe6, 0xf7, 0x1d, 0xcb, - 0x20, 0xae, 0xa7, 0x2a, 0xf9, 0xe4, 0xea, 0xe2, 0x46, 0x26, 0x5a, 0x72, 0x93, 0x29, 0x8a, 0xda, - 0x97, 0xbe, 0x36, 0x33, 0xf6, 0xb5, 0x80, 0x38, 0xf1, 0xb5, 0x25, 0xb6, 0x0c, 0x97, 0x11, 0x0e, - 0x14, 0xe8, 0x8b, 0x14, 0x98, 0xe3, 0x46, 0x70, 0x1d, 0x24, 0x4c, 0x43, 0x1c, 0x77, 0xee, 0xa9, - 0xaf, 0x25, 0xaa, 0xe5, 0xb1, 0xaf, 0x25, 0x4c, 0x63, 0xe2, 0x6b, 0x69, 0x66, 0x6d, 0x1a, 0xe8, - 0xb3, 0xc7, 0x37, 0x13, 0xd5, 0x32, 0x4e, 0x98, 0x06, 0x5c, 0x07, 0xb3, 0x96, 0xbe, 0x47, 0x2c, - 0x71, 0xb8, 0xea, 0xd8, 0xd7, 0x38, 0x30, 0xf1, 0xb5, 0x45, 0xc6, 0x67, 0x12, 0xc2, 0x1c, 0x85, - 0xef, 0x81, 0x05, 0x97, 0xe8, 0x46, 0xdb, 0xb1, 0xad, 0x63, 0x76, 0x90, 0xe9, 0x62, 0x6e, 0xec, - 0x6b, 0x69, 0x0a, 0xd6, 0x6d, 0xeb, 0x78, 0xe2, 0x6b, 0x17, 0x98, 0x59, 0x00, 0x20, 0x1c, 0xea, - 0x60, 0x1b, 0x40, 0xb3, 0x6b, 0x3b, 0x2e, 0x69, 0xf7, 0x89, 0xdb, 0x33, 0x59, 0x68, 0x3c, 0x35, - 0xc5, 0xbc, 0xbc, 0x3e, 0xf6, 0xb5, 0x15, 0xae, 0x6d, 0x44, 0xca, 0x89, 0xaf, 0x5d, 0xe5, 0xbb, - 0x3e, 0xa9, 0x41, 0x78, 0x9a, 0x0d, 0x3f, 0x02, 0xcb, 0x62, 0x01, 0x83, 0x58, 0x64, 0x40, 0xd4, - 0x59, 0xe6, 0xfb, 0xff, 0xc7, 0xbe, 0xb6, 0xc4, 0x15, 0x65, 0x86, 0x4f, 0x7c, 0x0d, 0x4a, 0x6e, - 0x39, 0x88, 0x70, 0x8c, 0x03, 0x0d, 0x70, 0xc9, 0x30, 0x3d, 0x7d, 0xcf, 0x22, 0xed, 0x01, 0xe9, - 0xf5, 0xdb, 0xa6, 0x6d, 0x90, 0x47, 0xc4, 0x53, 0xe7, 0x98, 0xcf, 0x8d, 0xb1, 0xaf, 0x41, 0xa1, - 0x6f, 0x91, 0x5e, 0xbf, 0xca, 0xb5, 0x13, 0x5f, 0x53, 0x79, 0x4d, 0x4d, 0xa9, 0x10, 0x3e, 0x85, - 0x0f, 0x37, 0xc0, 0x5c, 0x5f, 0x3f, 0xf4, 0x88, 0xa1, 0xce, 0x33, 0xbf, 0xd9, 0xb1, 0xaf, 0x09, - 0x24, 0x3c, 0x70, 0x2e, 0x22, 0x2c, 0x70, 0x9a, 0x3c, 0xbc, 0x4a, 0x3d, 0x35, 0x73, 0x32, 0x79, - 0xca, 0x4c, 0x11, 0x25, 0x8f, 0x20, 0x86, 0xbe, 0xb8, 0x8c, 0x70, 0xa0, 0x40, 0x7f, 0x9b, 0x03, - 0x73, 0xdc, 0x08, 0x16, 0xc3, 0xe4, 0x59, 0x2a, 0x6e, 0x50, 0x07, 0xff, 0xf4, 0xb5, 0x34, 0xd7, - 0x55, 0xcb, 0x67, 0x25, 0xd3, 0xa7, 0x8f, 0x6f, 0x2a, 0x52, 0x42, 0xad, 0x81, 0x94, 0xd4, 0x2c, - 0x58, 0xed, 0xd9, 0xbc, 0x4d, 0xf0, 0xda, 0xb3, 0x59, 0x83, 0x60, 0x18, 0x7c, 0x1f, 0x2c, 0xe8, - 0x86, 0x41, 0x6b, 0x84, 0x78, 0x6a, 0x32, 0x9f, 0xa4, 0x39, 0x3b, 0xf6, 0xb5, 0x08, 0x9c, 0xf8, - 0xda, 0x32, 0xb3, 0x12, 0x08, 0xc2, 0x91, 0x0e, 0xfe, 0x34, 0x5e, 0xb9, 0xa9, 0x93, 0x3d, 0xe0, - 0xdb, 0x95, 0x2c, 0xcd, 0xf4, 0x0e, 0x71, 0x45, 0xeb, 0x9b, 0xe5, 0x05, 0x45, 0x33, 0x9d, 0x82, - 0xa2, 0xf1, 0xf1, 0x4c, 0x0f, 0x00, 0x84, 0x43, 0x1d, 0xdc, 0x02, 0x4b, 0x3d, 0xfd, 0x51, 0xdb, - 0x23, 0x3f, 0x3b, 0x24, 0x76, 0x87, 0xb0, 0x9c, 0x49, 0xf2, 0x5d, 0xf4, 0xf4, 0x47, 0x4d, 0x01, - 0x87, 0xbb, 0x90, 0x30, 0x84, 0x65, 0x06, 0x2c, 0x02, 0x60, 0xda, 0x03, 0xd7, 0x31, 0x0e, 0x3b, - 0xc4, 0x15, 0x29, 0xc2, 0x3a, 0x70, 0x84, 0x86, 0x1d, 0x38, 0x82, 0x10, 0x96, 0xf4, 0xb0, 0x0b, - 0xd2, 0x2c, 0x77, 0xdb, 0xa6, 0xa1, 0xa6, 0xf3, 0xca, 0x6a, 0xaa, 0xb8, 0x23, 0x0e, 0x77, 0x9e, - 0x65, 0x21, 0x3b, 0xdb, 0xe0, 0x91, 0xe6, 0x0c, 0x63, 0x57, 0x8d, 0x30, 0xfa, 0x42, 0xa6, 0x7d, - 0x23, 0xa0, 0xfd, 0x2e, 0x7a, 0xc4, 0x01, 0x1f, 0xfe, 0x1c, 0x64, 0xbd, 0x07, 0x26, 0xad, 0x14, - 0xbe, 0xf6, 0xc0, 0x74, 0xec, 0xb6, 0x4b, 0x7a, 0xce, 0x91, 0x6e, 0x79, 0xea, 0x02, 0xdb, 0xfc, - 0xed, 0xb1, 0xaf, 0xa9, 0x94, 0x55, 0x95, 0x48, 0x58, 0x70, 0x26, 0xbe, 0x96, 0x63, 0x2b, 0x9e, - 0x45, 0x40, 0xf8, 0x4c, 0x5b, 0xf8, 0x08, 0xbc, 0x48, 0xec, 0x8e, 0x7b, 0xdc, 0x67, 0xcb, 0xf6, - 0x75, 0xcf, 0x7b, 0xe8, 0xb8, 0x46, 0x7b, 0xe0, 0x3c, 0x20, 0xb6, 0x0a, 0x58, 0x52, 0xbf, 0x3f, - 0xf6, 0xb5, 0xab, 0x11, 0xa9, 0x21, 0x38, 0x2d, 0x4a, 0x99, 0xf8, 0xda, 0x0d, 0xb6, 0xf6, 0x19, - 0x7a, 0x84, 0xcf, 0xb2, 0x44, 0xbf, 0x54, 0xc0, 0x2c, 0x0b, 0x06, 0xad, 0x66, 0xde, 0x94, 0x45, - 0x0b, 0x66, 0xd5, 0xcc, 0x91, 0xa9, 0xf6, 0x2d, 0x70, 0x58, 0x01, 0xb3, 0xfb, 0xa6, 0x45, 0x3c, - 0x35, 0xc1, 0x6a, 0x19, 0x4a, 0x17, 0x81, 0x69, 0x91, 0xaa, 0xbd, 0xef, 0x14, 0xaf, 0x89, 0x6a, - 0xe6, 0xc4, 0xb0, 0x96, 0xa8, 0x84, 0x30, 0x07, 0xd1, 0xa7, 0x0a, 0x58, 0x64, 0x9b, 0xb8, 0xd3, - 0x37, 0xf4, 0x01, 0xf9, 0x5f, 0x6e, 0xe5, 0x09, 0x00, 0xe9, 0xc0, 0x20, 0x6c, 0x08, 0xca, 0x39, - 0x1a, 0xc2, 0x1a, 0x48, 0x79, 0xe6, 0x27, 0x84, 0x5d, 0x2c, 0x49, 0xce, 0xa5, 0x72, 0xc8, 0xa5, - 0x02, 0xc2, 0x0c, 0x83, 0x1f, 0x00, 0xd0, 0x73, 0x0c, 0x73, 0xdf, 0x24, 0x46, 0xdb, 0x63, 0x05, - 0x9a, 0x2c, 0xe6, 0x69, 0xf7, 0x08, 0xd0, 0xe6, 0xc4, 0xd7, 0x5e, 0xe0, 0xe5, 0x15, 0x20, 0x08, - 0x47, 0x5a, 0xda, 0x3f, 0x42, 0x07, 0x7b, 0xc7, 0xea, 0x12, 0xab, 0x8c, 0xf7, 0x83, 0xca, 0x68, - 0x1e, 0x38, 0xee, 0x80, 0x95, 0x43, 0xb8, 0x4c, 0xf1, 0x38, 0x2c, 0xb5, 0x08, 0x42, 0xb4, 0x12, - 0x04, 0x19, 0x4b, 0x54, 0xb8, 0x03, 0xe6, 0x83, 0x81, 0x87, 0x66, 0x7e, 0xac, 0x49, 0xdf, 0x25, - 0x9d, 0x81, 0xe3, 0x16, 0xf3, 0x41, 0x93, 0x3e, 0x0a, 0x07, 0x20, 0x5e, 0x70, 0x47, 0xc1, 0xe8, - 0x13, 0x68, 0xe0, 0xbb, 0x20, 0x1d, 0x36, 0x13, 0xc0, 0x7e, 0x2b, 0x6b, 0x46, 0x5e, 0xd4, 0x49, - 0x78, 0x33, 0xf2, 0xc2, 0x36, 0x12, 0xea, 0xe0, 0x87, 0x60, 0x6e, 0xcf, 0x72, 0x3a, 0x0f, 0x82, - 0xdb, 0xe2, 0x62, 0xb4, 0x91, 0x22, 0xc5, 0xd9, 0xb9, 0xde, 0x10, 0x7b, 0x11, 0xd4, 0xf0, 0xfa, - 0x67, 0x22, 0xc2, 0x02, 0xa6, 0xd3, 0x9c, 0x77, 0xdc, 0xb3, 0x4c, 0xfb, 0x41, 0x7b, 0xa0, 0xbb, - 0x5d, 0x32, 0x50, 0x57, 0xa2, 0x69, 0x4e, 0x68, 0x5a, 0x4c, 0x11, 0x4e, 0x73, 0x31, 0x14, 0xe1, - 0x38, 0x8b, 0xce, 0x98, 0xdc, 0x75, 0xfb, 0x40, 0xf7, 0x0e, 0x54, 0xc8, 0xea, 0x94, 0x75, 0x38, - 0x0e, 0x6f, 0xeb, 0xde, 0x41, 0x18, 0xf6, 0x08, 0x42, 0x58, 0xd2, 0xc3, 0xdb, 0x60, 0x41, 0xd4, - 0x26, 0x31, 0xd4, 0x8b, 0xcc, 0x05, 0x4b, 0x85, 0x10, 0x0c, 0x53, 0x21, 0x44, 0x10, 0x8e, 0xb4, - 0xb0, 0x28, 0xe6, 0x48, 0x3e, 0xfd, 0x5d, 0x99, 0x4e, 0xfb, 0x73, 0x0c, 0x92, 0x9b, 0x60, 0xf1, - 0xe4, 0x54, 0xb3, 0xcc, 0x3b, 0x7e, 0x3f, 0x36, 0xcf, 0xf0, 0x8e, 0xdf, 0x97, 0x27, 0x19, 0x99, - 0x01, 0x3f, 0x94, 0xd2, 0xd2, 0xf6, 0xd4, 0xc5, 0xbc, 0xb2, 0x3a, 0x5b, 0x7c, 0x45, 0xce, 0xc3, - 0x9a, 0x37, 0x95, 0x87, 0x35, 0x0f, 0xfd, 0xc7, 0xd7, 0x92, 0xa6, 0x3d, 0xc0, 0x12, 0x0d, 0xee, - 0x03, 0x1e, 0xa5, 0x36, 0xab, 0xaa, 0x65, 0xe6, 0x6a, 0xeb, 0xa9, 0xaf, 0x2d, 0x61, 0xfd, 0x21, - 0x3b, 0xfa, 0xa6, 0xf9, 0x09, 0xa1, 0x81, 0xda, 0x0b, 0x84, 0x30, 0x50, 0x21, 0x12, 0x38, 0xfe, - 0xec, 0xf1, 0xcd, 0x98, 0x19, 0x8e, 0x8c, 0x60, 0x19, 0x2c, 0x5a, 0x4e, 0x47, 0xb7, 0xda, 0xfb, - 0x96, 0xde, 0xf5, 0xd4, 0x7f, 0xcd, 0xb3, 0x1f, 0xcf, 0x4e, 0x91, 0xe1, 0x9b, 0x14, 0x0e, 0x37, - 0x1d, 0x41, 0x08, 0x4b, 0x7a, 0xb8, 0x0d, 0x96, 0x44, 0xba, 0xf3, 0x5c, 0xf8, 0xf7, 0x3c, 0x3b, - 0x49, 0x16, 0x43, 0xa1, 0x10, 0xd9, 0xb0, 0x22, 0x57, 0x09, 0x4f, 0x07, 0x99, 0x01, 0xbf, 0x47, - 0x07, 0x24, 0x3a, 0xc4, 0x19, 0x62, 0x5a, 0xbb, 0xce, 0x47, 0x21, 0x06, 0x85, 0x55, 0x26, 0x64, - 0x36, 0x0b, 0xb1, 0x27, 0x88, 0xc1, 0xbc, 0x69, 0x1f, 0xe9, 0x96, 0x19, 0x4c, 0x63, 0xef, 0x3c, - 0xf5, 0x35, 0x80, 0xf5, 0x87, 0x55, 0x8e, 0xf2, 0xcb, 0x91, 0x3d, 0x4a, 0x97, 0x23, 0x93, 0xe9, - 0xe5, 0x28, 0x31, 0x71, 0xc0, 0xa3, 0x15, 0x63, 0x3b, 0xb1, 0x81, 0x37, 0xcd, 0x5c, 0xb3, 0x8a, - 0xb1, 0x9d, 0xf8, 0xb0, 0xcb, 0x2b, 0x26, 0x86, 0x22, 0x1c, 0x67, 0xbd, 0x9b, 0xfa, 0xed, 0xe7, - 0xda, 0x0c, 0x7a, 0xa2, 0x80, 0x85, 0xb0, 0x7a, 0x69, 0xe3, 0x64, 0x21, 0x4b, 0xb2, 0x88, 0xb1, - 0x44, 0x3d, 0xe0, 0xa1, 0xe2, 0x89, 0x7a, 0xc0, 0x62, 0xc4, 0x30, 0x7a, 0x31, 0x38, 0xfb, 0xfb, - 0x1e, 0x19, 0xb0, 0x96, 0x9c, 0xe4, 0x17, 0x03, 0x47, 0xc2, 0x8b, 0x81, 0x8b, 0x08, 0x0b, 0x1c, - 0xbe, 0x21, 0x1a, 0x73, 0x82, 0xa5, 0xd0, 0x8d, 0xd3, 0x1b, 0x73, 0x90, 0x81, 0xbc, 0x3f, 0xbf, - 0x07, 0x16, 0x1e, 0x12, 0xfd, 0x01, 0x3f, 0x4a, 0x5e, 0x0d, 0xac, 0x65, 0x51, 0x50, 0x1c, 0x23, - 0x6f, 0x59, 0x01, 0x80, 0x70, 0xa8, 0x13, 0xbf, 0xf1, 0x3e, 0x98, 0xe3, 0x9d, 0x12, 0x36, 0x40, - 0xba, 0xe3, 0x1c, 0xda, 0x83, 0xe8, 0x7d, 0x69, 0x45, 0x1e, 0xf4, 0x98, 0xa6, 0xf8, 0x7f, 0xa2, - 0x85, 0x85, 0xd4, 0xf0, 0x8c, 0x04, 0x40, 0x27, 0x34, 0xa1, 0x42, 0xbf, 0x52, 0xc0, 0xbc, 0x30, - 0x84, 0xdb, 0xe1, 0xdc, 0x9b, 0x2a, 0xbe, 0x73, 0xe2, 0x02, 0xf8, 0xfa, 0x77, 0x28, 0xb9, 0xf9, - 0x8b, 0xd7, 0xa9, 0x23, 0xdd, 0x3a, 0xe4, 0x81, 0x4a, 0xf1, 0xd7, 0x29, 0x06, 0x84, 0xfd, 0x94, - 0x49, 0x08, 0x73, 0x14, 0xfd, 0x22, 0x05, 0xe6, 0x31, 0xed, 0xd3, 0xde, 0x00, 0xbe, 0x1d, 0xee, - 0x62, 0xb6, 0xf8, 0xf2, 0x59, 0xcb, 0x46, 0xc5, 0x18, 0x0c, 0xdc, 0xd1, 0x3d, 0x9f, 0x38, 0xf7, - 0x3d, 0x1f, 0xdc, 0xc9, 0xc9, 0x73, 0xdc, 0xc9, 0x51, 0xba, 0xa4, 0x9e, 0x3b, 0x5d, 0x66, 0xcf, - 0x9f, 0x2e, 0x41, 0x06, 0xcf, 0x9d, 0x23, 0x83, 0xeb, 0xe0, 0xc2, 0xbe, 0xeb, 0xf4, 0xd8, 0x6b, - 0x99, 0xe3, 0xea, 0xee, 0xb1, 0xa8, 0x56, 0x56, 0x52, 0x54, 0xd3, 0x0a, 0x14, 0x61, 0x49, 0xc5, - 0x50, 0x84, 0xe3, 0xac, 0x78, 0xae, 0xa6, 0x9f, 0x2f, 0x57, 0xe1, 0x6d, 0x90, 0xe6, 0x4d, 0xd6, - 0x76, 0xd8, 0x4d, 0x3f, 0x5b, 0x7c, 0x89, 0xf6, 0x09, 0x86, 0xd5, 0x9c, 0x30, 0x07, 0x85, 0x1c, - 0xfe, 0xec, 0x80, 0x80, 0xfe, 0xac, 0x80, 0x34, 0x26, 0x5e, 0xdf, 0xb1, 0x3d, 0xf2, 0x4d, 0x93, - 0x60, 0x0d, 0xa4, 0x0c, 0x7d, 0xa0, 0xb3, 0x14, 0x10, 0xd1, 0xa3, 0x72, 0x18, 0x3d, 0x2a, 0x20, - 0xcc, 0x30, 0xf8, 0x01, 0x48, 0x75, 0x1c, 0x83, 0x1f, 0xfe, 0x05, 0x79, 0x18, 0xa8, 0xb8, 0xae, - 0xe3, 0x96, 0x1c, 0x43, 0xdc, 0x74, 0x94, 0x14, 0x3a, 0xa0, 0x02, 0xc2, 0x0c, 0x43, 0x7f, 0x52, - 0x40, 0xa6, 0xec, 0x3c, 0xb4, 0x2d, 0x47, 0x37, 0x1a, 0xae, 0xd3, 0xa5, 0x6f, 0x4c, 0xdf, 0x68, - 0xdc, 0x6c, 0x83, 0xf9, 0x43, 0x36, 0xac, 0x06, 0x03, 0xe7, 0xcd, 0xf8, 0xcd, 0x7b, 0x72, 0x11, - 0x3e, 0xd9, 0x46, 0xef, 0xb6, 0xc2, 0x38, 0xf4, 0xcf, 0x65, 0x84, 0x03, 0x05, 0xfa, 0x63, 0x12, - 0x64, 0xcf, 0x76, 0x04, 0x7b, 0x60, 0x91, 0x33, 0xdb, 0xd2, 0x57, 0xa4, 0xd5, 0xf3, 0xec, 0x81, - 0xcd, 0x03, 0xec, 0x7e, 0x3b, 0x0c, 0xe5, 0xf0, 0x7e, 0x8b, 0x20, 0x84, 0x25, 0xfd, 0x73, 0xbd, - 0x1a, 0x4b, 0xd3, 0x63, 0xf2, 0xdb, 0x4f, 0x8f, 0x4d, 0xb0, 0xcc, 0x53, 0x34, 0xf8, 0x86, 0x91, - 0xca, 0x27, 0x57, 0x67, 0x8b, 0xeb, 0x63, 0x5f, 0x5b, 0xda, 0xe3, 0x97, 0x48, 0xf0, 0xf5, 0x62, - 0x25, 0x4a, 0x56, 0x0e, 0x06, 0xd9, 0x96, 0x99, 0xc1, 0x31, 0x2e, 0xdc, 0x8c, 0x0d, 0x17, 0xbc, - 0xd4, 0xbf, 0x73, 0xce, 0x61, 0x42, 0x1a, 0x1e, 0xd0, 0x1c, 0x48, 0x35, 0x4c, 0xbb, 0x8b, 0xde, - 0x03, 0xb3, 0x25, 0xcb, 0xf1, 0x58, 0xc7, 0x71, 0x89, 0xee, 0x39, 0xb6, 0x9c, 0x4a, 0x1c, 0x09, - 0x8f, 0x9a, 0x8b, 0x08, 0x0b, 0x7c, 0xed, 0x8b, 0x24, 0x58, 0x94, 0x3e, 0xfa, 0xc1, 0x1f, 0x82, - 0x6b, 0xbb, 0x95, 0x66, 0xb3, 0xb0, 0x55, 0x69, 0xb7, 0xee, 0x35, 0x2a, 0xed, 0xd2, 0xce, 0x9d, - 0x66, 0xab, 0x82, 0xdb, 0xa5, 0x7a, 0x6d, 0xb3, 0xba, 0x95, 0x99, 0xc9, 0x5e, 0x1f, 0x8e, 0xf2, - 0xaa, 0x64, 0x11, 0xff, 0x3c, 0xf7, 0x5d, 0x00, 0x63, 0xe6, 0xd5, 0x5a, 0xb9, 0xf2, 0xe3, 0x8c, - 0x92, 0xbd, 0x34, 0x1c, 0xe5, 0x33, 0x92, 0x15, 0x7f, 0xeb, 0xfb, 0x01, 0x78, 0x71, 0x9a, 0xdd, - 0xbe, 0xd3, 0x28, 0x17, 0x5a, 0x95, 0x4c, 0x22, 0x9b, 0x1d, 0x8e, 0xf2, 0x57, 0x4e, 0x1a, 0x89, - 0x14, 0x7c, 0x1d, 0x5c, 0x8a, 0x99, 0xe2, 0xca, 0x8f, 0xee, 0x54, 0x9a, 0xad, 0x4c, 0x32, 0x7b, - 0x65, 0x38, 0xca, 0x43, 0xc9, 0x2a, 0xb8, 0x26, 0x36, 0xc0, 0xe5, 0x13, 0x16, 0xcd, 0x46, 0xbd, - 0xd6, 0xac, 0x64, 0x52, 0xd9, 0xab, 0xc3, 0x51, 0xfe, 0x62, 0xcc, 0x44, 0x74, 0x95, 0x12, 0xc8, - 0xc5, 0x6c, 0xca, 0xf5, 0x8f, 0x6b, 0x3b, 0xf5, 0x42, 0xb9, 0xdd, 0xc0, 0xf5, 0x2d, 0x5c, 0x69, - 0x36, 0x33, 0xb3, 0x59, 0x6d, 0x38, 0xca, 0x5f, 0x93, 0x8c, 0xa7, 0x2a, 0x7c, 0x0d, 0xac, 0xc4, - 0x9c, 0x34, 0xaa, 0xb5, 0xad, 0xcc, 0x5c, 0xf6, 0xe2, 0x70, 0x94, 0x7f, 0x41, 0xb2, 0xa3, 0x67, - 0x39, 0x15, 0xbf, 0xd2, 0x4e, 0xbd, 0x59, 0xc9, 0xcc, 0x4f, 0xc5, 0x8f, 0x1d, 0xf8, 0xda, 0x1f, - 0x14, 0x00, 0xa7, 0xbf, 0xb3, 0xc2, 0x77, 0x80, 0x1a, 0x38, 0x29, 0xd5, 0x77, 0x1b, 0x74, 0x9f, - 0xd5, 0x7a, 0xad, 0x5d, 0xab, 0xd7, 0x2a, 0x99, 0x99, 0x58, 0x54, 0x25, 0xab, 0x9a, 0x63, 0x13, - 0x58, 0x07, 0x57, 0x4f, 0xb3, 0xdc, 0xb9, 0xff, 0x56, 0x46, 0xc9, 0x6e, 0x0c, 0x47, 0xf9, 0xcb, - 0xd3, 0x86, 0x3b, 0xf7, 0xdf, 0xfa, 0xea, 0xd7, 0x2f, 0x9f, 0xae, 0x58, 0xfb, 0xbd, 0x02, 0x16, - 0xe5, 0xad, 0xbd, 0x01, 0x2e, 0xc9, 0x8e, 0x77, 0x2b, 0xad, 0x42, 0xb9, 0xd0, 0x2a, 0x64, 0x66, - 0xf8, 0x19, 0x48, 0xd4, 0x5d, 0x32, 0xd0, 0x59, 0xdb, 0x7d, 0x15, 0xac, 0xc4, 0x7e, 0x45, 0xe5, - 0x6e, 0x05, 0x07, 0x19, 0x25, 0xef, 0x9f, 0x1c, 0x11, 0x17, 0xbe, 0x06, 0xa0, 0x4c, 0x2e, 0xec, - 0x7c, 0x5c, 0xb8, 0xd7, 0xcc, 0x24, 0xb2, 0x97, 0x87, 0xa3, 0xfc, 0x8a, 0xc4, 0x2e, 0x58, 0x0f, - 0xf5, 0x63, 0x6f, 0xed, 0xaf, 0x09, 0xb0, 0x24, 0xbf, 0xaa, 0xc0, 0xd7, 0xc0, 0xc5, 0xcd, 0xea, - 0x0e, 0xcd, 0xc4, 0xcd, 0x3a, 0x3f, 0x01, 0x2a, 0x66, 0x66, 0xf8, 0x72, 0x32, 0x95, 0x3e, 0xc3, - 0xef, 0x03, 0xf5, 0x04, 0xbd, 0x5c, 0xc5, 0x95, 0x52, 0xab, 0x8e, 0xef, 0x65, 0x94, 0xec, 0x8b, - 0x34, 0x60, 0xb2, 0x4d, 0xd9, 0x74, 0x59, 0x0b, 0x3a, 0x86, 0xb7, 0xc1, 0xb5, 0x13, 0x86, 0xcd, - 0x7b, 0xbb, 0x3b, 0xd5, 0xda, 0x47, 0x7c, 0xbd, 0x44, 0xf6, 0xc6, 0x70, 0x94, 0xbf, 0x2a, 0xdb, - 0x36, 0xf9, 0xdb, 0x1f, 0x85, 0xd2, 0x0a, 0xdc, 0x06, 0xf9, 0x33, 0xec, 0xa3, 0x0d, 0x24, 0xb3, - 0x68, 0x38, 0xca, 0x5f, 0x3f, 0xc5, 0x49, 0xb8, 0x8f, 0xb4, 0x02, 0xdf, 0x04, 0x57, 0x4e, 0xf7, - 0x14, 0xd4, 0xc5, 0x29, 0xf6, 0x6b, 0x7f, 0x57, 0xc0, 0x42, 0x78, 0xeb, 0xd1, 0xa0, 0x55, 0x30, - 0xae, 0xd3, 0x26, 0x51, 0xae, 0xb4, 0x6b, 0xf5, 0x36, 0x93, 0x82, 0xa0, 0x85, 0xbc, 0x9a, 0xc3, - 0x1e, 0x69, 0x8e, 0x4b, 0xf4, 0xad, 0x4a, 0xad, 0x82, 0xab, 0xa5, 0xe0, 0x44, 0x43, 0xf6, 0x16, - 0xb1, 0x89, 0x6b, 0x76, 0xe0, 0x5b, 0xe0, 0x6a, 0xdc, 0x79, 0xf3, 0x4e, 0x69, 0x3b, 0x88, 0x12, - 0xdb, 0xa0, 0xb4, 0x40, 0xf3, 0xb0, 0x73, 0xc0, 0x0e, 0xe6, 0xed, 0x98, 0x55, 0xb5, 0x76, 0xb7, - 0xb0, 0x53, 0x2d, 0x73, 0xab, 0x64, 0x56, 0x1d, 0x8e, 0xf2, 0x97, 0x42, 0x2b, 0xf1, 0xe2, 0x41, - 0xcd, 0xd6, 0xbe, 0x52, 0x40, 0xee, 0xeb, 0x2f, 0x2f, 0xf8, 0x31, 0x78, 0x85, 0xc5, 0x6b, 0xaa, - 0x15, 0x88, 0xbe, 0xc5, 0x63, 0x58, 0x68, 0x34, 0x2a, 0xb5, 0x72, 0x66, 0x26, 0xbb, 0x3a, 0x1c, - 0xe5, 0x6f, 0x7e, 0xbd, 0xcb, 0x42, 0xbf, 0x4f, 0x6c, 0xe3, 0x9c, 0x8e, 0x37, 0xeb, 0x78, 0xab, - 0xd2, 0xca, 0x28, 0xe7, 0x71, 0xbc, 0xe9, 0xb8, 0x5d, 0x32, 0x28, 0xee, 0x7e, 0xf9, 0x24, 0x37, - 0xf3, 0xf8, 0x49, 0x6e, 0xe6, 0xcb, 0xa7, 0x39, 0xe5, 0xf1, 0xd3, 0x9c, 0xf2, 0x9b, 0x67, 0xb9, - 0x99, 0xcf, 0x9f, 0xe5, 0x94, 0xc7, 0xcf, 0x72, 0x33, 0xff, 0x78, 0x96, 0x9b, 0xb9, 0xff, 0x6a, - 0xd7, 0x1c, 0x1c, 0x1c, 0xee, 0xad, 0x77, 0x9c, 0xde, 0x2d, 0xef, 0xd8, 0xee, 0x0c, 0x0e, 0x4c, - 0xbb, 0x2b, 0x3d, 0xc9, 0xff, 0xb7, 0xed, 0xcd, 0xb1, 0xa7, 0x37, 0xff, 0x1b, 0x00, 0x00, 0xff, - 0xff, 0xf7, 0xe3, 0xa9, 0xd7, 0x86, 0x1b, 0x00, 0x00, + // 2920 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0x4f, 0x6c, 0x1b, 0xc7, + 0xd5, 0xd7, 0x92, 0x94, 0x44, 0x8d, 0x64, 0x87, 0x1a, 0xff, 0x63, 0x68, 0x5b, 0xcb, 0x6f, 0xe2, + 0x7c, 0x9f, 0xa2, 0x7c, 0xb1, 0x13, 0x27, 0xf9, 0xbe, 0x34, 0x4e, 0x1d, 0x88, 0x22, 0x25, 0x33, + 0x91, 0x49, 0x65, 0x28, 0xdb, 0xb5, 0xd1, 0x82, 0x58, 0x71, 0x47, 0xd4, 0xc2, 0xe4, 0x2e, 0xbb, + 0x4b, 0xea, 0x4f, 0xd0, 0x4b, 0x5b, 0xa0, 0x08, 0x74, 0x28, 0x8a, 0x9c, 0x8a, 0xa2, 0x42, 0x83, + 0x02, 0x45, 0x6f, 0x05, 0x7a, 0xe8, 0xa1, 0x39, 0xf5, 0xe8, 0xa3, 0x11, 0xa0, 0x40, 0xd1, 0xc3, + 0x02, 0xb1, 0x2f, 0x2d, 0x8f, 0x3c, 0xf6, 0x54, 0xcc, 0x9b, 0xd9, 0xd9, 0x59, 0xfd, 0x09, 0x94, + 0xe4, 0xd0, 0xdb, 0xbe, 0xdf, 0xfb, 0xb3, 0xc3, 0x37, 0xef, 0xfd, 0xe6, 0xcd, 0x12, 0x5d, 0xec, + 0x38, 0x1b, 0x37, 0x7a, 0xbe, 0xd7, 0xf7, 0x5a, 0x5e, 0xe7, 0xc6, 0x06, 0xeb, 0x5d, 0x07, 0x01, + 0x67, 0x23, 0xac, 0x30, 0xc5, 0x76, 0xfb, 0x02, 0x2c, 0xbc, 0xe4, 0xb3, 0x9e, 0x17, 0x08, 0xf3, + 0x8d, 0xc1, 0xe6, 0x8d, 0xb6, 0xd7, 0xf6, 0x40, 0x80, 0x27, 0x61, 0x44, 0x9e, 0x19, 0x68, 0xfc, + 0x0e, 0xeb, 0x74, 0x3c, 0xbc, 0x84, 0xa6, 0x6d, 0xb6, 0xed, 0xb4, 0x58, 0xd3, 0xb5, 0xba, 0x2c, + 0x6f, 0x14, 0x8d, 0xf9, 0xa9, 0x12, 0x19, 0x86, 0x26, 0x12, 0x70, 0xcd, 0xea, 0xb2, 0x51, 0x68, + 0xe6, 0x76, 0xbb, 0x9d, 0x77, 0x49, 0x0c, 0x11, 0xaa, 0xe9, 0x79, 0x90, 0x56, 0xc7, 0x61, 0x6e, + 0x5f, 0x04, 0x49, 0xc5, 0x41, 0x04, 0x9c, 0x08, 0x12, 0x43, 0x84, 0x6a, 0x7a, 0x5c, 0x47, 0x67, + 0x65, 0x90, 0x6d, 0xe6, 0x07, 0x8e, 0xe7, 0xe6, 0xd3, 0x10, 0x67, 0x7e, 0x18, 0x9a, 0x67, 0x84, + 0xe6, 0xbe, 0x50, 0x8c, 0x42, 0xf3, 0x9c, 0x16, 0x4a, 0xa2, 0x84, 0x26, 0xad, 0xc8, 0x1f, 0x0d, + 0x34, 0x71, 0x87, 0x59, 0x36, 0xf3, 0xf1, 0x22, 0xca, 0xf4, 0xf7, 0x7a, 0xe2, 0xe7, 0x9d, 0xbd, + 0x79, 0xe1, 0x7a, 0x94, 0xb8, 0xeb, 0x77, 0x59, 0x10, 0x58, 0x6d, 0xb6, 0xbe, 0xd7, 0x63, 0xa5, + 0x8b, 0xc3, 0xd0, 0x04, 0xb3, 0x51, 0x68, 0x22, 0x88, 0xcf, 0x05, 0x42, 0x01, 0xc3, 0x36, 0x9a, + 0x6e, 0x79, 0xdd, 0x9e, 0xcf, 0x02, 0x58, 0x5b, 0x0a, 0x22, 0x5d, 0x39, 0x12, 0x69, 0x29, 0xb6, + 0x29, 0x5d, 0x1b, 0x86, 0xa6, 0xee, 0x34, 0x0a, 0xcd, 0x59, 0xb1, 0xee, 0x18, 0x23, 0x54, 0xb7, + 0x20, 0xdf, 0x47, 0x67, 0x96, 0x3a, 0x83, 0xa0, 0xcf, 0xfc, 0x25, 0xcf, 0xdd, 0x74, 0xda, 0xf8, + 0x43, 0x34, 0xb9, 0xe9, 0x75, 0x6c, 0xe6, 0x07, 0x79, 0xa3, 0x98, 0x9e, 0x9f, 0xbe, 0x99, 0x8b, + 0x5f, 0xb9, 0x0c, 0x8a, 0x92, 0xf9, 0x24, 0x34, 0xc7, 0x86, 0xa1, 0x19, 0x19, 0x8e, 0x42, 0x73, + 0x06, 0x5e, 0x23, 0x64, 0x42, 0x23, 0x05, 0xf9, 0x3c, 0x83, 0x26, 0x84, 0x13, 0xbe, 0x8e, 0x52, + 0x8e, 0x2d, 0xb7, 0x7b, 0xee, 0x59, 0x68, 0xa6, 0xaa, 0xe5, 0x61, 0x68, 0xa6, 0x1c, 0x7b, 0x14, + 0x9a, 0x59, 0xf0, 0x76, 0x6c, 0xf2, 0xe9, 0xd3, 0x6b, 0xa9, 0x6a, 0x99, 0xa6, 0x1c, 0x1b, 0x5f, + 0x47, 0xe3, 0x1d, 0x6b, 0x83, 0x75, 0xe4, 0xe6, 0xe6, 0x87, 0xa1, 0x29, 0x80, 0x51, 0x68, 0x4e, + 0x83, 0x3d, 0x48, 0x84, 0x0a, 0x14, 0xdf, 0x42, 0x53, 0x3e, 0xb3, 0xec, 0xa6, 0xe7, 0x76, 0xf6, + 0x60, 0x23, 0xb3, 0xa5, 0xb9, 0x61, 0x68, 0x66, 0x39, 0x58, 0x77, 0x3b, 0x7b, 0xa3, 0xd0, 0x3c, + 0x0b, 0x6e, 0x11, 0x40, 0xa8, 0xd2, 0xe1, 0x26, 0xc2, 0x4e, 0xdb, 0xf5, 0x7c, 0xd6, 0xec, 0x31, + 0xbf, 0xeb, 0x40, 0x6a, 0x82, 0x7c, 0x06, 0xa2, 0xbc, 0x3e, 0x0c, 0xcd, 0x59, 0xa1, 0x5d, 0x8b, + 0x95, 0xa3, 0xd0, 0xbc, 0x24, 0x56, 0x7d, 0x58, 0x43, 0xe8, 0x51, 0x6b, 0xfc, 0x21, 0x3a, 0x23, + 0x5f, 0x60, 0xb3, 0x0e, 0xeb, 0xb3, 0xfc, 0x38, 0xc4, 0xfe, 0xef, 0x61, 0x68, 0xce, 0x08, 0x45, + 0x19, 0xf0, 0x51, 0x68, 0x62, 0x2d, 0xac, 0x00, 0x09, 0x4d, 0xd8, 0x60, 0x1b, 0x9d, 0xb7, 0x9d, + 0xc0, 0xda, 0xe8, 0xb0, 0x66, 0x9f, 0x75, 0x7b, 0x4d, 0xc7, 0xb5, 0xd9, 0x2e, 0x0b, 0xf2, 0x13, + 0x10, 0xf3, 0xe6, 0x30, 0x34, 0xb1, 0xd4, 0xaf, 0xb3, 0x6e, 0xaf, 0x2a, 0xb4, 0xa3, 0xd0, 0xcc, + 0x8b, 0x9e, 0x3a, 0xa2, 0x22, 0xf4, 0x18, 0x7b, 0x7c, 0x13, 0x4d, 0xf4, 0xac, 0x41, 0xc0, 0xec, + 0xfc, 0x24, 0xc4, 0x2d, 0x0c, 0x43, 0x53, 0x22, 0x6a, 0xc3, 0x85, 0x48, 0xa8, 0xc4, 0x79, 0xf1, + 0x88, 0x2e, 0x0d, 0xf2, 0xb9, 0xc3, 0xc5, 0x53, 0x06, 0x45, 0x5c, 0x3c, 0xd2, 0x50, 0xc5, 0x12, + 0x32, 0xa1, 0x91, 0x82, 0xfc, 0x65, 0x02, 0x4d, 0x08, 0x27, 0x5c, 0x52, 0xc5, 0x33, 0x53, 0xba, + 0xc9, 0x03, 0xfc, 0x3d, 0x34, 0xb3, 0x42, 0x57, 0x2d, 0x9f, 0x54, 0x4c, 0x9f, 0x3c, 0xbd, 0x66, + 0x68, 0x05, 0xb5, 0x80, 0x32, 0x1a, 0x59, 0x40, 0xef, 0xb9, 0x82, 0x26, 0x44, 0xef, 0xb9, 0x40, + 0x10, 0x80, 0xe1, 0xf7, 0xd0, 0x94, 0x65, 0xdb, 0xbc, 0x47, 0x58, 0x90, 0x4f, 0x17, 0xd3, 0xbc, + 0x66, 0x87, 0xa1, 0x19, 0x83, 0xa3, 0xd0, 0x3c, 0x03, 0x5e, 0x12, 0x21, 0x34, 0xd6, 0xe1, 0x1f, + 0x24, 0x3b, 0x37, 0x73, 0x98, 0x03, 0xbe, 0x5d, 0xcb, 0xf2, 0x4a, 0x6f, 0x31, 0x5f, 0x52, 0xdf, + 0xb8, 0x68, 0x28, 0x5e, 0xe9, 0x1c, 0x94, 0xc4, 0x27, 0x2a, 0x3d, 0x02, 0x08, 0x55, 0x3a, 0xbc, + 0x82, 0x66, 0xba, 0xd6, 0x6e, 0x33, 0x60, 0x3f, 0x1c, 0x30, 0xb7, 0xc5, 0xa0, 0x66, 0xd2, 0x62, + 0x15, 0x5d, 0x6b, 0xb7, 0x21, 0x61, 0xb5, 0x0a, 0x0d, 0x23, 0x54, 0xb7, 0xc0, 0x25, 0x84, 0x1c, + 0xb7, 0xef, 0x7b, 0xf6, 0xa0, 0xc5, 0x7c, 0x59, 0x22, 0xc0, 0xc0, 0x31, 0xaa, 0x18, 0x38, 0x86, + 0x08, 0xd5, 0xf4, 0xb8, 0x8d, 0xb2, 0x50, 0xbb, 0x4d, 0xc7, 0xce, 0x67, 0x8b, 0xc6, 0x7c, 0xa6, + 0xb4, 0x2a, 0x37, 0x77, 0x12, 0xaa, 0x10, 0xf6, 0x36, 0x7a, 0xe4, 0x35, 0x03, 0xd6, 0x55, 0x5b, + 0x65, 0x5f, 0xca, 0x9c, 0x37, 0x22, 0xb3, 0x5f, 0xc5, 0x8f, 0x34, 0xb2, 0xc7, 0x3f, 0x42, 0x85, + 0xe0, 0xb1, 0xc3, 0x3b, 0x45, 0xbc, 0xbb, 0xef, 0x78, 0x6e, 0xd3, 0x67, 0x5d, 0x6f, 0xdb, 0xea, + 0x04, 0xf9, 0x29, 0x58, 0xfc, 0xed, 0x61, 0x68, 0xe6, 0xb9, 0x55, 0x55, 0x33, 0xa2, 0xd2, 0x66, + 0x14, 0x9a, 0x73, 0xf0, 0xc6, 0x93, 0x0c, 0x08, 0x3d, 0xd1, 0x17, 0xef, 0xa2, 0x17, 0x99, 0xdb, + 0xf2, 0xf7, 0x7a, 0xf0, 0xda, 0x9e, 0x15, 0x04, 0x3b, 0x9e, 0x6f, 0x37, 0xfb, 0xde, 0x63, 0xe6, + 0xe6, 0x11, 0x14, 0xf5, 0x7b, 0xc3, 0xd0, 0xbc, 0x14, 0x1b, 0xad, 0x49, 0x9b, 0x75, 0x6e, 0x32, + 0x0a, 0xcd, 0xab, 0xf0, 0xee, 0x13, 0xf4, 0x84, 0x9e, 0xe4, 0x49, 0x7e, 0x62, 0xa0, 0x71, 0x48, + 0x06, 0xef, 0x66, 0x41, 0xca, 0x92, 0x82, 0xa1, 0x9b, 0x05, 0x72, 0x84, 0xbe, 0x25, 0x8e, 0x2b, + 0x68, 0x7c, 0xd3, 0xe9, 0xb0, 0x20, 0x9f, 0x82, 0x5e, 0xc6, 0xda, 0x41, 0xe0, 0x74, 0x58, 0xd5, + 0xdd, 0xf4, 0x4a, 0x97, 0x65, 0x37, 0x0b, 0x43, 0xd5, 0x4b, 0x5c, 0x22, 0x54, 0x80, 0xe4, 0x13, + 0x03, 0x4d, 0xc3, 0x22, 0xee, 0xf5, 0x6c, 0xab, 0xcf, 0xfe, 0x93, 0x4b, 0xf9, 0xf3, 0x34, 0xca, + 0x46, 0x0e, 0x8a, 0x10, 0x8c, 0x53, 0x10, 0xc2, 0x02, 0xca, 0x04, 0xce, 0xc7, 0x0c, 0x0e, 0x96, + 0xb4, 0xb0, 0xe5, 0xb2, 0xb2, 0xe5, 0x02, 0xa1, 0x80, 0xe1, 0xf7, 0x11, 0xea, 0x7a, 0xb6, 0xb3, + 0xe9, 0x30, 0xbb, 0x19, 0x40, 0x83, 0xa6, 0x4b, 0x45, 0xce, 0x1e, 0x11, 0xda, 0x18, 0x85, 0xe6, + 0x0b, 0xa2, 0xbd, 0x22, 0x84, 0xd0, 0x58, 0xcb, 0xf9, 0x43, 0x05, 0xd8, 0xd8, 0xcb, 0xcf, 0x40, + 0x67, 0xbc, 0x17, 0x75, 0x46, 0x63, 0xcb, 0xf3, 0xfb, 0xd0, 0x0e, 0xea, 0x35, 0xa5, 0x3d, 0xd5, + 0x6a, 0x31, 0x44, 0x78, 0x27, 0x48, 0x63, 0xaa, 0x99, 0xe2, 0x55, 0x34, 0x19, 0x0d, 0x3c, 0xbc, + 0xf2, 0x13, 0x24, 0x7d, 0x9f, 0xb5, 0xfa, 0x9e, 0x5f, 0x2a, 0x46, 0x24, 0xbd, 0xad, 0x06, 0x20, + 0xd1, 0x70, 0xdb, 0xd1, 0xe8, 0x13, 0x69, 0xf0, 0xbb, 0x28, 0xab, 0xc8, 0x04, 0xc1, 0x6f, 0x05, + 0x32, 0x0a, 0x62, 0x26, 0x11, 0x64, 0x14, 0x28, 0x1a, 0x51, 0x3a, 0xfc, 0x01, 0x9a, 0xd8, 0xe8, + 0x78, 0xad, 0xc7, 0xd1, 0x69, 0x71, 0x2e, 0x5e, 0x48, 0x89, 0xe3, 0xb0, 0xaf, 0x57, 0xe5, 0x5a, + 0xa4, 0xa9, 0x3a, 0xfe, 0x41, 0x24, 0x54, 0xc2, 0x7c, 0x9a, 0x0b, 0xf6, 0xba, 0x1d, 0xc7, 0x7d, + 0xdc, 0xec, 0x5b, 0x7e, 0x9b, 0xf5, 0xf3, 0xb3, 0xf1, 0x34, 0x27, 0x35, 0xeb, 0xa0, 0x50, 0xd3, + 0x5c, 0x02, 0x25, 0x34, 0x69, 0xc5, 0x67, 0x4c, 0x11, 0xba, 0xb9, 0x65, 0x05, 0x5b, 0x79, 0x0c, + 0x7d, 0x0a, 0x0c, 0x27, 0xe0, 0x3b, 0x56, 0xb0, 0xa5, 0xd2, 0x1e, 0x43, 0x84, 0x6a, 0x7a, 0x7c, + 0x1b, 0x4d, 0xc9, 0xde, 0x64, 0x76, 0xfe, 0x1c, 0x84, 0x80, 0x52, 0x50, 0xa0, 0x2a, 0x05, 0x85, + 0x10, 0x1a, 0x6b, 0x71, 0x49, 0xce, 0x91, 0x62, 0xfa, 0xbb, 0x78, 0xb4, 0xec, 0x4f, 0x31, 0x48, + 0x2e, 0xa3, 0xe9, 0xc3, 0x53, 0xcd, 0x19, 0xc1, 0xf8, 0xbd, 0xc4, 0x3c, 0x23, 0x18, 0xbf, 0xa7, + 0x4f, 0x32, 0xba, 0x05, 0xfe, 0x40, 0x2b, 0x4b, 0x37, 0xc8, 0x4f, 0x17, 0x8d, 0xf9, 0xf1, 0xd2, + 0x2b, 0x7a, 0x1d, 0xd6, 0x82, 0x23, 0x75, 0x58, 0x0b, 0xc8, 0xbf, 0x42, 0x33, 0xed, 0xb8, 0x7d, + 0xaa, 0x99, 0xe1, 0x4d, 0x24, 0xb2, 0xd4, 0x84, 0xae, 0x3a, 0x03, 0xa1, 0x56, 0x9e, 0x85, 0xe6, + 0x0c, 0xb5, 0x76, 0x60, 0xeb, 0x1b, 0xce, 0xc7, 0x8c, 0x27, 0x6a, 0x23, 0x12, 0x54, 0xa2, 0x14, + 0x12, 0x05, 0xfe, 0xf4, 0xe9, 0xb5, 0x84, 0x1b, 0x8d, 0x9d, 0xf0, 0x7d, 0x94, 0xed, 0x75, 0xac, + 0xfe, 0xa6, 0xe7, 0x77, 0xf3, 0x67, 0xa1, 0xd8, 0xb5, 0x1c, 0xae, 0x49, 0x4d, 0xd9, 0xea, 0x5b, + 0x25, 0x22, 0xcb, 0x4c, 0xd9, 0xab, 0xca, 0x8d, 0x00, 0x42, 0x95, 0x0e, 0x97, 0xd1, 0x74, 0xc7, + 0x6b, 0x59, 0x9d, 0xe6, 0x66, 0xc7, 0x6a, 0x07, 0xf9, 0x7f, 0x4c, 0x42, 0x52, 0xa1, 0x3a, 0x00, + 0x5f, 0xe6, 0xb0, 0x4a, 0x46, 0x0c, 0x11, 0xaa, 0xe9, 0xf1, 0x1d, 0x34, 0x23, 0xdb, 0x48, 0xd4, + 0xd8, 0x3f, 0x27, 0xa1, 0x42, 0x60, 0x6f, 0xa4, 0x42, 0x56, 0xd9, 0xac, 0xde, 0x7d, 0xa2, 0xcc, + 0x74, 0x0b, 0xfc, 0x7f, 0x7c, 0xf0, 0xe2, 0xc3, 0xa1, 0x2d, 0xa7, 0xc0, 0x2b, 0x62, 0xc4, 0x02, + 0x48, 0x75, 0xaf, 0x94, 0x61, 0xc6, 0x82, 0x27, 0x4c, 0xd1, 0xa4, 0xe3, 0x6e, 0x5b, 0x1d, 0x27, + 0x9a, 0xf2, 0xde, 0x79, 0x16, 0x9a, 0x88, 0x5a, 0x3b, 0x55, 0x81, 0x8a, 0x43, 0x17, 0x1e, 0xb5, + 0x43, 0x17, 0x64, 0x7e, 0xe8, 0x6a, 0x96, 0x34, 0xb2, 0xe3, 0x9d, 0xe8, 0x7a, 0x89, 0x41, 0x3a, + 0x0b, 0xa1, 0xa1, 0x13, 0x5d, 0x2f, 0x39, 0x44, 0x8b, 0x4e, 0x4c, 0xa0, 0x84, 0x26, 0xad, 0xde, + 0xcd, 0xfc, 0xf2, 0x33, 0x73, 0x8c, 0x7c, 0x69, 0xa0, 0x29, 0xc5, 0x0a, 0x9c, 0x90, 0x21, 0x65, + 0x69, 0xc8, 0x18, 0x34, 0xc0, 0x96, 0x48, 0x95, 0x68, 0x80, 0x2d, 0xc8, 0x11, 0x60, 0xfc, 0xc0, + 0xf1, 0x36, 0x37, 0x03, 0xd6, 0x07, 0xaa, 0x4f, 0x8b, 0x03, 0x47, 0x20, 0xea, 0xc0, 0x11, 0x22, + 0xa1, 0x12, 0xc7, 0x6f, 0x48, 0xc2, 0x4f, 0x41, 0x69, 0x5e, 0x3d, 0x9e, 0xf0, 0xa3, 0xca, 0x16, + 0xbc, 0x7f, 0x0b, 0x4d, 0xed, 0x30, 0xeb, 0xb1, 0xd8, 0x4a, 0xd1, 0x65, 0x40, 0x85, 0x1c, 0x94, + 0xdb, 0x28, 0x0a, 0x2a, 0x02, 0x08, 0x55, 0x3a, 0xf9, 0x1b, 0x1f, 0xa1, 0x09, 0xc1, 0xc0, 0x78, + 0x0d, 0x65, 0x5b, 0xde, 0xc0, 0xed, 0xc7, 0xf7, 0xb0, 0x59, 0x7d, 0x80, 0x04, 0x4d, 0xe9, 0xbf, + 0xa2, 0x9a, 0x8d, 0x4c, 0xd5, 0x1e, 0x49, 0x80, 0x4f, 0x7e, 0x52, 0x45, 0x7e, 0x6a, 0xa0, 0x49, + 0xe9, 0x88, 0xef, 0xa8, 0x79, 0x3a, 0x53, 0x7a, 0xe7, 0xd0, 0xc1, 0xf2, 0xd5, 0x77, 0x33, 0xfd, + 0x50, 0x91, 0xd7, 0xb4, 0x6d, 0xab, 0x33, 0x10, 0x89, 0xca, 0x88, 0x6b, 0x1a, 0x00, 0x8a, 0xa7, + 0x41, 0x22, 0x54, 0xa0, 0xe4, 0x77, 0x06, 0x9a, 0xd1, 0xfb, 0x8e, 0x33, 0xdc, 0xc0, 0x75, 0x76, + 0x61, 0x31, 0x89, 0x83, 0xfd, 0x9e, 0xeb, 0xec, 0x42, 0x67, 0x16, 0x9e, 0x84, 0xa6, 0xc1, 0x37, + 0x80, 0xdb, 0xa9, 0x0d, 0xe0, 0x02, 0xa1, 0x80, 0xe1, 0x8f, 0xd0, 0xe4, 0x8e, 0xe3, 0xda, 0xde, + 0x4e, 0x00, 0xcb, 0x98, 0xd6, 0x87, 0xed, 0x07, 0x42, 0x01, 0x91, 0x8a, 0x32, 0x52, 0x64, 0xad, + 0xd2, 0x25, 0x65, 0x42, 0x23, 0x0d, 0xf9, 0x59, 0x0a, 0x65, 0xa3, 0x15, 0xf0, 0x13, 0xdd, 0xdb, + 0x71, 0x99, 0xaf, 0x7f, 0xb2, 0x00, 0x1a, 0x07, 0x54, 0xce, 0xdc, 0x82, 0x9d, 0x14, 0x42, 0x68, + 0xac, 0xe5, 0x01, 0xda, 0xbe, 0x37, 0xe8, 0xe9, 0x9f, 0x2b, 0x20, 0x00, 0xa0, 0x89, 0x00, 0x0a, + 0x21, 0x34, 0xd6, 0xe2, 0x5b, 0x28, 0x3d, 0x70, 0x6c, 0xa8, 0xf6, 0xf1, 0xd2, 0x2b, 0xcf, 0x42, + 0x33, 0x7d, 0x0f, 0xf6, 0x88, 0xa3, 0xa3, 0xd0, 0x9c, 0x12, 0x29, 0x71, 0x6c, 0x8d, 0x13, 0xb9, + 0x05, 0xe5, 0x7a, 0xee, 0xdc, 0x76, 0x6c, 0x28, 0x49, 0xe9, 0xbc, 0x22, 0x9c, 0xdb, 0x9a, 0x73, + 0x3b, 0xe9, 0xbc, 0xc2, 0x9d, 0x39, 0xf6, 0x6b, 0x03, 0x4d, 0x6b, 0x39, 0xfc, 0xf6, 0xb9, 0x58, + 0x45, 0x67, 0x45, 0x00, 0x27, 0x68, 0xc2, 0x0f, 0x84, 0x7c, 0xc8, 0xbb, 0x30, 0x68, 0xaa, 0xc1, + 0x0a, 0xc7, 0xd5, 0x5d, 0x58, 0x07, 0x09, 0x4d, 0xd8, 0x90, 0x1f, 0x67, 0xd0, 0x24, 0xe5, 0xf3, + 0x44, 0xd0, 0xc7, 0x6f, 0xab, 0xaa, 0x1e, 0x2f, 0xbd, 0x7c, 0x52, 0x19, 0xc7, 0xbf, 0x31, 0xba, + 0x18, 0xc6, 0xf3, 0x68, 0xea, 0xd4, 0xf3, 0x68, 0x34, 0x3b, 0xa6, 0x4f, 0x31, 0x3b, 0xc6, 0xf4, + 0x93, 0xf9, 0xda, 0xf4, 0x33, 0x7e, 0x7a, 0xfa, 0x89, 0x18, 0x71, 0xe2, 0x14, 0x8c, 0x58, 0x47, + 0x67, 0x37, 0x7d, 0xaf, 0x0b, 0x9f, 0x0f, 0x3c, 0xdf, 0xf2, 0xf7, 0x24, 0xfb, 0x03, 0x45, 0x73, + 0xcd, 0x7a, 0xa4, 0x50, 0x14, 0x9d, 0x40, 0x09, 0x4d, 0x5a, 0x25, 0xb9, 0x2f, 0xfb, 0xf5, 0xb8, + 0x0f, 0xdf, 0x46, 0x59, 0x31, 0x0c, 0xb8, 0x1e, 0x4c, 0xa4, 0xe3, 0xa5, 0x97, 0x78, 0x93, 0x02, + 0x56, 0xf3, 0x54, 0x93, 0x4a, 0x59, 0xfd, 0xec, 0xc8, 0x80, 0xfc, 0xc1, 0x40, 0x59, 0xca, 0x82, + 0x9e, 0xe7, 0x06, 0xec, 0x9b, 0x16, 0xc1, 0x02, 0xca, 0xd8, 0x56, 0xdf, 0x82, 0x12, 0x90, 0xd9, + 0xe3, 0xb2, 0xca, 0x1e, 0x17, 0x08, 0x05, 0x0c, 0xbf, 0x8f, 0x32, 0x2d, 0xcf, 0x16, 0x9b, 0x7f, + 0x56, 0x1f, 0x5a, 0x2b, 0xbe, 0xef, 0xf9, 0x4b, 0x9e, 0x2d, 0x27, 0x32, 0x6e, 0xa4, 0x02, 0x70, + 0x81, 0x50, 0xc0, 0xc8, 0xef, 0x0d, 0x94, 0x2b, 0x7b, 0x3b, 0x6e, 0xc7, 0xb3, 0xec, 0x35, 0xdf, + 0x6b, 0xf3, 0x9b, 0xfd, 0x37, 0xba, 0x16, 0x35, 0xd1, 0xe4, 0x00, 0x2e, 0x55, 0xd1, 0xc5, 0xe8, + 0x5a, 0x72, 0x42, 0x3c, 0xfc, 0x12, 0x71, 0x03, 0x8b, 0xbf, 0xc1, 0x48, 0x67, 0x15, 0x5f, 0xc8, + 0x84, 0x46, 0x0a, 0xf2, 0xdb, 0x34, 0x2a, 0x9c, 0x1c, 0x08, 0x77, 0xd1, 0xb4, 0xb0, 0x6c, 0x6a, + 0x5f, 0x3b, 0xe7, 0x4f, 0xb3, 0x06, 0x98, 0x5b, 0x61, 0x5e, 0x1a, 0x28, 0x59, 0xcd, 0x4b, 0x31, + 0x44, 0xa8, 0xa6, 0xff, 0x5a, 0x9f, 0x70, 0xb4, 0x5b, 0x4e, 0xfa, 0xdb, 0xdf, 0x72, 0x1a, 0xe8, + 0x8c, 0x28, 0xd1, 0xe8, 0x5b, 0x5b, 0xa6, 0x98, 0x9e, 0x1f, 0x2f, 0x5d, 0xe7, 0x9c, 0xb5, 0x21, + 0x86, 0x92, 0xe8, 0x2b, 0xdb, 0x6c, 0x5c, 0xac, 0x02, 0x8c, 0xaa, 0x2d, 0x37, 0x46, 0x13, 0xb6, + 0x78, 0x39, 0x31, 0x04, 0x8b, 0x56, 0xff, 0x9f, 0x53, 0x0e, 0xbd, 0xda, 0x90, 0x4b, 0x26, 0x50, + 0x66, 0xcd, 0x71, 0xdb, 0xe4, 0x16, 0x1a, 0x5f, 0xea, 0x78, 0x01, 0x30, 0x8e, 0xcf, 0xac, 0xc0, + 0x73, 0xf5, 0x52, 0x12, 0x88, 0xda, 0x6a, 0x21, 0x12, 0x2a, 0xf1, 0x85, 0xcf, 0xd3, 0x68, 0x5a, + 0xfb, 0x38, 0x8d, 0xbf, 0x8b, 0x2e, 0xdf, 0xad, 0x34, 0x1a, 0x8b, 0x2b, 0x95, 0xe6, 0xfa, 0xc3, + 0xb5, 0x4a, 0x73, 0x69, 0xf5, 0x5e, 0x63, 0xbd, 0x42, 0x9b, 0x4b, 0xf5, 0xda, 0x72, 0x75, 0x25, + 0x37, 0x56, 0xb8, 0xb2, 0x7f, 0x50, 0xcc, 0x6b, 0x1e, 0xc9, 0xcf, 0xc8, 0xff, 0x8b, 0x70, 0xc2, + 0xbd, 0x5a, 0x2b, 0x57, 0xbe, 0x97, 0x33, 0x0a, 0xe7, 0xf7, 0x0f, 0x8a, 0x39, 0xcd, 0x4b, 0x7c, + 0x9d, 0xf8, 0x0e, 0x7a, 0xf1, 0xa8, 0x75, 0xf3, 0xde, 0x5a, 0x79, 0x71, 0xbd, 0x92, 0x4b, 0x15, + 0x0a, 0xfb, 0x07, 0xc5, 0x8b, 0x87, 0x9d, 0x64, 0x09, 0xbe, 0x8e, 0xce, 0x27, 0x5c, 0x69, 0xe5, + 0xa3, 0x7b, 0x95, 0xc6, 0x7a, 0x2e, 0x5d, 0xb8, 0xb8, 0x7f, 0x50, 0xc4, 0x9a, 0x57, 0x74, 0x4c, + 0xdc, 0x44, 0x17, 0x0e, 0x79, 0x34, 0xd6, 0xea, 0xb5, 0x46, 0x25, 0x97, 0x29, 0x5c, 0xda, 0x3f, + 0x28, 0x9e, 0x4b, 0xb8, 0x48, 0x56, 0x59, 0x42, 0x73, 0x09, 0x9f, 0x72, 0xfd, 0x41, 0x6d, 0xb5, + 0xbe, 0x58, 0x6e, 0xae, 0xd1, 0xfa, 0x0a, 0xad, 0x34, 0x1a, 0xb9, 0xf1, 0x82, 0xb9, 0x7f, 0x50, + 0xbc, 0xac, 0x39, 0x1f, 0xe9, 0xf0, 0x05, 0x34, 0x9b, 0x08, 0xb2, 0x56, 0xad, 0xad, 0xe4, 0x26, + 0x0a, 0xe7, 0xf6, 0x0f, 0x8a, 0x2f, 0x68, 0x7e, 0x7c, 0x2f, 0x8f, 0xe4, 0x6f, 0x69, 0xb5, 0xde, + 0xa8, 0xe4, 0x26, 0x8f, 0xe4, 0x0f, 0x36, 0x7c, 0xe1, 0x37, 0x06, 0xc2, 0x47, 0xff, 0x0f, 0xc0, + 0xef, 0xa0, 0x7c, 0x14, 0x64, 0xa9, 0x7e, 0x77, 0x8d, 0xaf, 0xb3, 0x5a, 0xaf, 0x35, 0x6b, 0xf5, + 0x5a, 0x25, 0x37, 0x96, 0xc8, 0xaa, 0xe6, 0x55, 0xf3, 0x5c, 0x86, 0xeb, 0xe8, 0xd2, 0x71, 0x9e, + 0xab, 0x8f, 0xde, 0xca, 0x19, 0x85, 0x9b, 0xfb, 0x07, 0xc5, 0x0b, 0x47, 0x1d, 0x57, 0x1f, 0xbd, + 0xf5, 0xc5, 0xcf, 0x5f, 0x3e, 0x5e, 0xb1, 0xc0, 0xc7, 0x08, 0x7d, 0x69, 0x6f, 0xa0, 0xf3, 0x7a, + 0xe0, 0xbb, 0x95, 0xf5, 0xc5, 0xf2, 0xe2, 0xfa, 0x62, 0x6e, 0x4c, 0xec, 0x81, 0x66, 0x7a, 0x97, + 0xf5, 0x2d, 0xa0, 0xdd, 0x57, 0xd1, 0x6c, 0xe2, 0x57, 0x54, 0xee, 0x57, 0x68, 0x54, 0x51, 0xfa, + 0xfa, 0xd9, 0x36, 0xf3, 0xf1, 0x6b, 0x08, 0xeb, 0xc6, 0x8b, 0xab, 0x0f, 0x16, 0x1f, 0x36, 0x72, + 0xa9, 0xc2, 0x85, 0xfd, 0x83, 0xe2, 0xac, 0x66, 0xbd, 0xd8, 0xd9, 0xb1, 0xf6, 0x82, 0x85, 0x3f, + 0xa5, 0xd0, 0x8c, 0x7e, 0xa5, 0xc6, 0xaf, 0xa1, 0x73, 0xcb, 0xd5, 0x55, 0x5e, 0x89, 0xcb, 0x75, + 0xb1, 0x03, 0x5c, 0xcc, 0x8d, 0x89, 0xd7, 0xe9, 0xa6, 0xfc, 0x19, 0xff, 0x3f, 0xca, 0x1f, 0x32, + 0x2f, 0x57, 0x69, 0x65, 0x69, 0xbd, 0x4e, 0x1f, 0xe6, 0x8c, 0xc2, 0x8b, 0x3c, 0x61, 0xba, 0x4f, + 0xd9, 0xf1, 0x81, 0x82, 0xf6, 0xf0, 0x6d, 0x74, 0xf9, 0x90, 0x63, 0xe3, 0xe1, 0xdd, 0xd5, 0x6a, + 0xed, 0x43, 0xf1, 0xbe, 0x54, 0xe1, 0xea, 0xfe, 0x41, 0xf1, 0x92, 0xee, 0xdb, 0x10, 0x5f, 0x29, + 0x38, 0x94, 0x35, 0xf0, 0x1d, 0x54, 0x3c, 0xc1, 0x3f, 0x5e, 0x40, 0xba, 0x40, 0xf6, 0x0f, 0x8a, + 0x57, 0x8e, 0x09, 0xa2, 0xd6, 0x91, 0x35, 0xf0, 0x9b, 0xe8, 0xe2, 0xf1, 0x91, 0xa2, 0xbe, 0x38, + 0xc6, 0x7f, 0xe1, 0xaf, 0x06, 0x9a, 0x52, 0xa7, 0x1e, 0x4f, 0x5a, 0x85, 0xd2, 0x3a, 0x27, 0x89, + 0x72, 0xa5, 0x59, 0xab, 0x37, 0x41, 0x8a, 0x92, 0xa6, 0xec, 0x6a, 0x1e, 0x3c, 0xf2, 0x1a, 0xd7, + 0xcc, 0x57, 0x2a, 0xb5, 0x0a, 0xad, 0x2e, 0x45, 0x3b, 0xaa, 0xac, 0x57, 0x98, 0xcb, 0x7c, 0xa7, + 0x85, 0xdf, 0x42, 0x97, 0x92, 0xc1, 0x1b, 0xf7, 0x96, 0xee, 0x44, 0x59, 0x82, 0x05, 0x6a, 0x2f, + 0x68, 0x0c, 0x5a, 0x5b, 0xb0, 0x31, 0x6f, 0x27, 0xbc, 0xaa, 0xb5, 0xfb, 0x8b, 0xab, 0xd5, 0xb2, + 0xf0, 0x4a, 0x17, 0xf2, 0xfb, 0x07, 0xc5, 0xf3, 0xca, 0x4b, 0x5e, 0x64, 0xb9, 0xdb, 0xc2, 0x17, + 0x06, 0x9a, 0xfb, 0xea, 0xc3, 0x0b, 0x3f, 0x40, 0xaf, 0x40, 0xbe, 0x8e, 0x50, 0x81, 0xe4, 0x2d, + 0x91, 0xc3, 0xc5, 0xb5, 0xb5, 0x4a, 0xad, 0x9c, 0x1b, 0x2b, 0xcc, 0xef, 0x1f, 0x14, 0xaf, 0x7d, + 0x75, 0xc8, 0xc5, 0x5e, 0x8f, 0xb9, 0xf6, 0x29, 0x03, 0x2f, 0xd7, 0xe9, 0x4a, 0x65, 0x3d, 0x67, + 0x9c, 0x26, 0xf0, 0xb2, 0xe7, 0xb7, 0x59, 0xbf, 0x74, 0xf7, 0xc9, 0x97, 0x73, 0x63, 0x4f, 0xbf, + 0x9c, 0x1b, 0x7b, 0xf2, 0x6c, 0xce, 0x78, 0xfa, 0x6c, 0xce, 0xf8, 0xc5, 0xf3, 0xb9, 0xb1, 0xcf, + 0x9e, 0xcf, 0x19, 0x4f, 0x9f, 0xcf, 0x8d, 0xfd, 0xed, 0xf9, 0xdc, 0xd8, 0xa3, 0x57, 0xdb, 0x4e, + 0x7f, 0x6b, 0xb0, 0x71, 0xbd, 0xe5, 0x75, 0x6f, 0x04, 0x7b, 0x6e, 0xab, 0xbf, 0xe5, 0xb8, 0x6d, + 0xed, 0x49, 0xff, 0x5f, 0x78, 0x63, 0x02, 0x9e, 0xde, 0xfc, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xc7, 0x92, 0x60, 0x1e, 0x2e, 0x1e, 0x00, 0x00, } func (m *Hello) Marshal() (dAtA []byte, err error) { @@ -1582,6 +1723,16 @@ func (m *FileInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x82 } } + { + size, err := m.Platform.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintBep(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 if m.RawBlockSize != 0 { i = encodeVarintBep(dAtA, i, uint64(m.RawBlockSize)) i-- @@ -1787,6 +1938,140 @@ func (m *Counter) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PlatformData) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PlatformData) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PlatformData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Windows != nil { + { + size, err := m.Windows.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintBep(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Unix != nil { + { + size, err := m.Unix.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintBep(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *UnixData) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UnixData) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UnixData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.GID != 0 { + i = encodeVarintBep(dAtA, i, uint64(m.GID)) + i-- + dAtA[i] = 0x20 + } + if m.UID != 0 { + i = encodeVarintBep(dAtA, i, uint64(m.UID)) + i-- + dAtA[i] = 0x18 + } + if len(m.GroupName) > 0 { + i -= len(m.GroupName) + copy(dAtA[i:], m.GroupName) + i = encodeVarintBep(dAtA, i, uint64(len(m.GroupName))) + i-- + dAtA[i] = 0x12 + } + if len(m.OwnerName) > 0 { + i -= len(m.OwnerName) + copy(dAtA[i:], m.OwnerName) + i = encodeVarintBep(dAtA, i, uint64(len(m.OwnerName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *WindowsData) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WindowsData) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WindowsData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.OwnerIsGroup { + i-- + if m.OwnerIsGroup { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if len(m.OwnerName) > 0 { + i -= len(m.OwnerName) + copy(dAtA[i:], m.OwnerName) + i = encodeVarintBep(dAtA, i, uint64(len(m.OwnerName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Request) Marshal() (dAtA []byte, err error) { size := m.ProtoSize() dAtA = make([]byte, size) @@ -2287,6 +2572,8 @@ func (m *FileInfo) ProtoSize() (n int) { if m.RawBlockSize != 0 { n += 1 + sovBep(uint64(m.RawBlockSize)) } + l = m.Platform.ProtoSize() + n += 1 + l + sovBep(uint64(l)) if len(m.Blocks) > 0 { for _, e := range m.Blocks { l = e.ProtoSize() @@ -2367,6 +2654,62 @@ func (m *Counter) ProtoSize() (n int) { return n } +func (m *PlatformData) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Unix != nil { + l = m.Unix.ProtoSize() + n += 1 + l + sovBep(uint64(l)) + } + if m.Windows != nil { + l = m.Windows.ProtoSize() + n += 1 + l + sovBep(uint64(l)) + } + return n +} + +func (m *UnixData) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.OwnerName) + if l > 0 { + n += 1 + l + sovBep(uint64(l)) + } + l = len(m.GroupName) + if l > 0 { + n += 1 + l + sovBep(uint64(l)) + } + if m.UID != 0 { + n += 1 + sovBep(uint64(m.UID)) + } + if m.GID != 0 { + n += 1 + sovBep(uint64(m.GID)) + } + return n +} + +func (m *WindowsData) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.OwnerName) + if l > 0 { + n += 1 + l + sovBep(uint64(l)) + } + if m.OwnerIsGroup { + n += 2 + } + return n +} + func (m *Request) ProtoSize() (n int) { if m == nil { return 0 @@ -3912,6 +4255,39 @@ func (m *FileInfo) Unmarshal(dAtA []byte) error { break } } + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Platform", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthBep + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthBep + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Platform.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 16: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Blocks", wireType) @@ -4433,6 +4809,382 @@ func (m *Counter) Unmarshal(dAtA []byte) error { } return nil } +func (m *PlatformData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PlatformData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PlatformData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Unix", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthBep + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthBep + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Unix == nil { + m.Unix = &UnixData{} + } + if err := m.Unix.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Windows", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthBep + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthBep + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Windows == nil { + m.Windows = &WindowsData{} + } + if err := m.Windows.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipBep(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthBep + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UnixData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UnixData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UnixData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OwnerName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthBep + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthBep + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OwnerName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthBep + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthBep + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GroupName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType) + } + m.UID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UID |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GID", wireType) + } + m.GID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GID |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipBep(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthBep + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WindowsData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WindowsData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WindowsData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OwnerName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthBep + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthBep + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OwnerName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OwnerIsGroup", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBep + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.OwnerIsGroup = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipBep(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthBep + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Request) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/lib/protocol/bep_extensions.go b/lib/protocol/bep_extensions.go index 719aa61029c..078e122167e 100644 --- a/lib/protocol/bep_extensions.go +++ b/lib/protocol/bep_extensions.go @@ -53,14 +53,14 @@ func (m Hello) Magic() uint32 { func (f FileInfo) String() string { switch f.Type { case FileInfoTypeDirectory: - return fmt.Sprintf("Directory{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, VersionHash:%x, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v}", - f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.VersionHash, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions) + return fmt.Sprintf("Directory{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, VersionHash:%x, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, Platform:%v}", + f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.VersionHash, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.Platform) case FileInfoTypeFile: - return fmt.Sprintf("File{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, VersionHash:%x, Length:%d, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, BlockSize:%d, Blocks:%v, BlocksHash:%x}", - f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.VersionHash, f.Size, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.RawBlockSize, f.Blocks, f.BlocksHash) + return fmt.Sprintf("File{Name:%q, Sequence:%d, Permissions:0%o, ModTime:%v, Version:%v, VersionHash:%x, Length:%d, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, BlockSize:%d, Blocks:%v, BlocksHash:%x, Platform:%v}", + f.Name, f.Sequence, f.Permissions, f.ModTime(), f.Version, f.VersionHash, f.Size, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.RawBlockSize, f.Blocks, f.BlocksHash, f.Platform) case FileInfoTypeSymlink, FileInfoTypeSymlinkDirectory, FileInfoTypeSymlinkFile: - return fmt.Sprintf("Symlink{Name:%q, Type:%v, Sequence:%d, Version:%v, VersionHash:%x, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, SymlinkTarget:%q}", - f.Name, f.Type, f.Sequence, f.Version, f.VersionHash, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.SymlinkTarget) + return fmt.Sprintf("Symlink{Name:%q, Type:%v, Sequence:%d, Version:%v, VersionHash:%x, Deleted:%v, Invalid:%v, LocalFlags:0x%x, NoPermissions:%v, SymlinkTarget:%q, Platform:%v}", + f.Name, f.Type, f.Sequence, f.Version, f.VersionHash, f.Deleted, f.RawInvalid, f.LocalFlags, f.NoPermissions, f.SymlinkTarget, f.Platform) default: panic("mystery file type detected") } @@ -190,30 +190,42 @@ func WinsConflict(f, other FileIntf) bool { return f.FileVersion().Compare(other.FileVersion()) == ConcurrentGreater } +type FileInfoComparison struct { + ModTimeWindow time.Duration + IgnorePerms bool + IgnoreBlocks bool + IgnoreFlags uint32 + IgnoreOwnership bool +} + func (f FileInfo) IsEquivalent(other FileInfo, modTimeWindow time.Duration) bool { - return f.isEquivalent(other, modTimeWindow, false, false, 0) + return f.isEquivalent(other, FileInfoComparison{ModTimeWindow: modTimeWindow}) } -func (f FileInfo) IsEquivalentOptional(other FileInfo, modTimeWindow time.Duration, ignorePerms bool, ignoreBlocks bool, ignoreFlags uint32) bool { - return f.isEquivalent(other, modTimeWindow, ignorePerms, ignoreBlocks, ignoreFlags) +func (f FileInfo) IsEquivalentOptional(other FileInfo, comp FileInfoComparison) bool { + return f.isEquivalent(other, comp) } // isEquivalent checks that the two file infos represent the same actual file content, // i.e. it does purposely not check only selected (see below) struct members. // Permissions (config) and blocks (scanning) can be excluded from the comparison. // Any file info is not "equivalent", if it has different -// - type -// - deleted flag -// - invalid flag -// - permissions, unless they are ignored +// - type +// - deleted flag +// - invalid flag +// - permissions, unless they are ignored +// // A file is not "equivalent", if it has different -// - modification time (difference bigger than modTimeWindow) -// - size -// - blocks, unless there are no blocks to compare (scanning) +// - modification time (difference bigger than modTimeWindow) +// - size +// - blocks, unless there are no blocks to compare (scanning) +// - os data +// // A symlink is not "equivalent", if it has different -// - target +// - target +// // A directory does not have anything specific to check. -func (f FileInfo) isEquivalent(other FileInfo, modTimeWindow time.Duration, ignorePerms bool, ignoreBlocks bool, ignoreFlags uint32) bool { +func (f FileInfo) isEquivalent(other FileInfo, comp FileInfoComparison) bool { if f.MustRescan() || other.MustRescan() { // These are per definition not equivalent because they don't // represent a valid state, even if both happen to have the @@ -222,20 +234,37 @@ func (f FileInfo) isEquivalent(other FileInfo, modTimeWindow time.Duration, igno } // Mask out the ignored local flags before checking IsInvalid() below - f.LocalFlags &^= ignoreFlags - other.LocalFlags &^= ignoreFlags + f.LocalFlags &^= comp.IgnoreFlags + other.LocalFlags &^= comp.IgnoreFlags if f.Name != other.Name || f.Type != other.Type || f.Deleted != other.Deleted || f.IsInvalid() != other.IsInvalid() { return false } - if !ignorePerms && !f.NoPermissions && !other.NoPermissions && !PermsEqual(f.Permissions, other.Permissions) { + // OS data comparison is special: we consider a difference only if an + // entry for the same OS exists on both sides and they are different. + // Otherwise a file would become different as soon as it's synced from + // Windows to Linux, as Linux would add a new POSIX entry for the file. + if !comp.IgnoreOwnership && f.Platform != other.Platform { + if f.Platform.Unix != nil && other.Platform.Unix != nil { + if *f.Platform.Unix != *other.Platform.Unix { + return false + } + } + if f.Platform.Windows != nil && other.Platform.Windows != nil { + if *f.Platform.Windows != *other.Platform.Windows { + return false + } + } + } + + if !comp.IgnorePerms && !f.NoPermissions && !other.NoPermissions && !PermsEqual(f.Permissions, other.Permissions) { return false } switch f.Type { case FileInfoTypeFile: - return f.Size == other.Size && ModTimeEqual(f.ModTime(), other.ModTime(), modTimeWindow) && (ignoreBlocks || f.BlocksEqual(other)) + return f.Size == other.Size && ModTimeEqual(f.ModTime(), other.ModTime(), comp.ModTimeWindow) && (comp.IgnoreBlocks || f.BlocksEqual(other)) case FileInfoTypeSymlink: return f.SymlinkTarget == other.SymlinkTarget case FileInfoTypeDirectory: diff --git a/lib/protocol/protocol_test.go b/lib/protocol/protocol_test.go index 54e3ec70e45..f9bb7c47674 100644 --- a/lib/protocol/protocol_test.go +++ b/lib/protocol/protocol_test.go @@ -872,10 +872,10 @@ func TestIsEquivalent(t *testing.T) { continue } - if res := tc.a.isEquivalent(tc.b, 0, ignPerms, ignBlocks, tc.ignFlags); res != tc.eq { + if res := tc.a.isEquivalent(tc.b, FileInfoComparison{IgnorePerms: ignPerms, IgnoreBlocks: ignBlocks, IgnoreFlags: tc.ignFlags}); res != tc.eq { t.Errorf("Case %d:\na: %v\nb: %v\na.IsEquivalent(b, %v, %v) => %v, expected %v", i, tc.a, tc.b, ignPerms, ignBlocks, res, tc.eq) } - if res := tc.b.isEquivalent(tc.a, 0, ignPerms, ignBlocks, tc.ignFlags); res != tc.eq { + if res := tc.b.isEquivalent(tc.a, FileInfoComparison{IgnorePerms: ignPerms, IgnoreBlocks: ignBlocks, IgnoreFlags: tc.ignFlags}); res != tc.eq { t.Errorf("Case %d:\na: %v\nb: %v\nb.IsEquivalent(a, %v, %v) => %v, expected %v", i, tc.a, tc.b, ignPerms, ignBlocks, res, tc.eq) } } diff --git a/lib/scanner/virtualfs_test.go b/lib/scanner/virtualfs_test.go index 365747565c4..5eff7c11ede 100644 --- a/lib/scanner/virtualfs_test.go +++ b/lib/scanner/virtualfs_test.go @@ -15,6 +15,7 @@ import ( "time" "github.com/syncthing/syncthing/lib/fs" + "github.com/syncthing/syncthing/lib/protocol" ) type infiniteFS struct { @@ -54,6 +55,10 @@ func (i infiniteFS) Open(name string) (fs.File, error) { return &fakeFile{name, i.filesize, 0}, nil } +func (i infiniteFS) PlatformData(name string) (protocol.PlatformData, error) { + return protocol.PlatformData{}, nil +} + type singleFileFS struct { fs.Filesystem name string @@ -100,6 +105,10 @@ func (s singleFileFS) Options() []fs.Option { return nil } +func (s singleFileFS) PlatformData(name string) (protocol.PlatformData, error) { + return protocol.PlatformData{}, nil +} + type fakeInfo struct { name string size int64 diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index 447cb0f0978..71618a15e4b 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -40,9 +40,10 @@ type Config struct { // The Filesystem provides an abstraction on top of the actual filesystem. Filesystem fs.Filesystem // If IgnorePerms is true, changes to permission bits will not be - // detected. Scanned files will get zero permission bits and the - // NoPermissionBits flag set. + // detected. IgnorePerms bool + // If IgnoreOwnership is true, changes to ownership will not be detected. + IgnoreOwnership bool // When AutoNormalize is set, file names that are in UTF8 but incorrect // normalization form will be corrected. AutoNormalize bool @@ -381,13 +382,22 @@ func (w *walker) walkRegular(ctx context.Context, relPath string, info fs.FileIn } } - f, _ := CreateFileInfo(info, relPath, nil) + f, err := CreateFileInfo(info, relPath, w.Filesystem) + if err != nil { + return err + } f = w.updateFileInfo(f, curFile) f.NoPermissions = w.IgnorePerms f.RawBlockSize = blockSize if hasCurFile { - if curFile.IsEquivalentOptional(f, w.ModTimeWindow, w.IgnorePerms, true, w.LocalFlags) { + if curFile.IsEquivalentOptional(f, protocol.FileInfoComparison{ + ModTimeWindow: w.ModTimeWindow, + IgnorePerms: w.IgnorePerms, + IgnoreBlocks: true, + IgnoreFlags: w.LocalFlags, + IgnoreOwnership: w.IgnoreOwnership, + }) { l.Debugln(w, "unchanged:", curFile, info.ModTime().Unix(), info.Mode()&fs.ModePerm) return nil } @@ -416,12 +426,21 @@ func (w *walker) walkRegular(ctx context.Context, relPath string, info fs.FileIn func (w *walker) walkDir(ctx context.Context, relPath string, info fs.FileInfo, finishedChan chan<- ScanResult) error { curFile, hasCurFile := w.CurrentFiler.CurrentFile(relPath) - f, _ := CreateFileInfo(info, relPath, nil) + f, err := CreateFileInfo(info, relPath, w.Filesystem) + if err != nil { + return err + } f = w.updateFileInfo(f, curFile) f.NoPermissions = w.IgnorePerms if hasCurFile { - if curFile.IsEquivalentOptional(f, w.ModTimeWindow, w.IgnorePerms, true, w.LocalFlags) { + if curFile.IsEquivalentOptional(f, protocol.FileInfoComparison{ + ModTimeWindow: w.ModTimeWindow, + IgnorePerms: w.IgnorePerms, + IgnoreBlocks: true, + IgnoreFlags: w.LocalFlags, + IgnoreOwnership: w.IgnoreOwnership, + }) { l.Debugln(w, "unchanged:", curFile, info.ModTime().Unix(), info.Mode()&fs.ModePerm) return nil } @@ -466,7 +485,13 @@ func (w *walker) walkSymlink(ctx context.Context, relPath string, info fs.FileIn f = w.updateFileInfo(f, curFile) if hasCurFile { - if curFile.IsEquivalentOptional(f, w.ModTimeWindow, w.IgnorePerms, true, w.LocalFlags) { + if curFile.IsEquivalentOptional(f, protocol.FileInfoComparison{ + ModTimeWindow: w.ModTimeWindow, + IgnorePerms: w.IgnorePerms, + IgnoreBlocks: true, + IgnoreFlags: w.LocalFlags, + IgnoreOwnership: w.IgnoreOwnership, + }) { l.Debugln(w, "unchanged:", curFile, info.ModTime().Unix(), info.Mode()&fs.ModePerm) return nil } @@ -550,17 +575,28 @@ func (w *walker) normalizePath(path string, info fs.FileInfo) (normPath string, return "", errUTF8Conflict } -// updateFileInfo updates walker specific members of protocol.FileInfo that do not depend on type -func (w *walker) updateFileInfo(file, curFile protocol.FileInfo) protocol.FileInfo { - if file.Type == protocol.FileInfoTypeFile && runtime.GOOS == "windows" { +// updateFileInfo updates walker specific members of protocol.FileInfo that +// do not depend on type, and things that should be preserved from the +// previous version of the FileInfo. +func (w *walker) updateFileInfo(dst, src protocol.FileInfo) protocol.FileInfo { + if dst.Type == protocol.FileInfoTypeFile && runtime.GOOS == "windows" { // If we have an existing index entry, copy the executable bits // from there. - file.Permissions |= (curFile.Permissions & 0111) + dst.Permissions |= (src.Permissions & 0111) } - file.Version = curFile.Version.Update(w.ShortID) - file.ModifiedBy = w.ShortID - file.LocalFlags = w.LocalFlags - return file + dst.Version = src.Version.Update(w.ShortID) + dst.ModifiedBy = w.ShortID + dst.LocalFlags = w.LocalFlags + + // Copy OS data from src to dst, unless it was already set on dst. + if dst.Platform.Unix == nil { + dst.Platform.Unix = src.Platform.Unix + } + if dst.Platform.Windows == nil { + dst.Platform.Windows = src.Platform.Windows + } + + return dst } func handleError(ctx context.Context, context, path string, err error, finishedChan chan<- ScanResult) { @@ -632,6 +668,11 @@ func (noCurrentFiler) CurrentFile(name string) (protocol.FileInfo, bool) { func CreateFileInfo(fi fs.FileInfo, name string, filesystem fs.Filesystem) (protocol.FileInfo, error) { f := protocol.FileInfo{Name: name} + if plat, err := filesystem.PlatformData(name); err == nil { + f.Platform = plat + } else { + return protocol.FileInfo{}, fmt.Errorf("reading platform data: %w", err) + } if fi.IsSymlink() { f.Type = protocol.FileInfoTypeSymlink target, err := filesystem.ReadSymlink(name) diff --git a/lib/scanner/walk_test.go b/lib/scanner/walk_test.go index 00f2456d73b..165cd718379 100644 --- a/lib/scanner/walk_test.go +++ b/lib/scanner/walk_test.go @@ -543,6 +543,79 @@ func TestWalkReceiveOnly(t *testing.T) { } } +func TestScanOwnershipPOSIX(t *testing.T) { + // This test works on all operating systems because the FakeFS is always POSIXy. + + fakeFS := fs.NewFilesystem(fs.FilesystemTypeFake, "TestScanOwnership") + current := make(fakeCurrentFiler) + + fakeFS.Create("root-owned") + fakeFS.Create("user-owned") + fakeFS.Lchown("user-owned", "1234", "5678") + fakeFS.Mkdir("user-owned-dir", 0755) + fakeFS.Lchown("user-owned-dir", "2345", "6789") + + expected := []struct { + name string + uid, gid int + }{ + {"root-owned", 0, 0}, + {"user-owned", 1234, 5678}, + {"user-owned-dir", 2345, 6789}, + } + + files := walkDir(fakeFS, ".", current, nil, 0) + if len(files) != len(expected) { + t.Fatalf("expected %d items, not %d", len(expected), len(files)) + } + for i := range expected { + if files[i].Name != expected[i].name { + t.Errorf("expected %s, got %s", expected[i].name, files[i].Name) + continue + } + + if files[i].Platform.Unix == nil { + t.Error("failed to load POSIX data on", files[i].Name) + continue + } + if files[i].Platform.Unix.UID != expected[i].uid { + t.Errorf("expected %d, got %d", expected[i].uid, files[i].Platform.Unix.UID) + } + if files[i].Platform.Unix.GID != expected[i].gid { + t.Errorf("expected %d, got %d", expected[i].gid, files[i].Platform.Unix.GID) + } + } +} + +func TestScanOwnershipWindows(t *testing.T) { + if runtime.GOOS != "windows" { + t.Skip("This test only works on Windows") + } + + testFS := fs.NewFilesystem(fs.FilesystemTypeBasic, t.TempDir()) + current := make(fakeCurrentFiler) + + fd, err := testFS.Create("user-owned") + if err != nil { + t.Fatal(err) + } + fd.Close() + + files := walkDir(testFS, ".", current, nil, 0) + if len(files) != 1 { + t.Fatalf("expected %d items, not %d", 1, len(files)) + } + t.Log(files[0]) + + // The file should have an owner name set. + if files[0].Platform.Windows == nil { + t.Fatal("failed to load Windows data") + } + if files[0].Platform.Windows.OwnerName == "" { + t.Errorf("expected owner name to be set") + } +} + func walkDir(fs fs.Filesystem, dir string, cfiler CurrentFiler, matcher *ignore.Matcher, localFlags uint32) []protocol.FileInfo { cfg, cancel := testConfig() defer cancel() diff --git a/proto/lib/config/folderconfiguration.proto b/proto/lib/config/folderconfiguration.proto index a0a838186cc..1f76bde6a95 100644 --- a/proto/lib/config/folderconfiguration.proto +++ b/proto/lib/config/folderconfiguration.proto @@ -54,6 +54,7 @@ message FolderConfiguration { fs.CopyRangeMethod copy_range_method = 32 [(ext.default) = "standard"]; bool case_sensitive_fs = 33 [(ext.goname) = "CaseSensitiveFS", (ext.xml) = "caseSensitiveFS", (ext.json) = "caseSensitiveFS"]; bool follow_junctions = 34 [(ext.goname) = "JunctionsAsDirs", (ext.xml) = "junctionsAsDirs", (ext.json) = "junctionsAsDirs"]; + bool sync_ownership = 35; // Legacy deprecated bool read_only = 9000 [deprecated=true, (ext.xml) = "ro,attr,omitempty"]; diff --git a/proto/lib/db/structs.proto b/proto/lib/db/structs.proto index f27acda328f..9bb8300aad7 100644 --- a/proto/lib/db/structs.proto +++ b/proto/lib/db/structs.proto @@ -36,6 +36,7 @@ message FileInfoTruncated { uint32 permissions = 4; int32 modified_ns = 11; int32 block_size = 13 [(ext.goname) = "RawBlockSize"]; + protocol.PlatformData platform = 14; // see bep.proto uint32 local_flags = 1000; diff --git a/proto/lib/protocol/bep.proto b/proto/lib/protocol/bep.proto index b12c9491480..167cd22cf2a 100644 --- a/proto/lib/protocol/bep.proto +++ b/proto/lib/protocol/bep.proto @@ -107,6 +107,7 @@ message FileInfo { uint32 permissions = 4; int32 modified_ns = 11; int32 block_size = 13 [(ext.goname) = "RawBlockSize"]; + PlatformData platform = 14; // The local_flags fields stores flags that are relevant to the local // host only. It is not part of the protocol, doesn't get sent or @@ -147,6 +148,29 @@ message Counter { uint64 value = 2; } +message PlatformData { + UnixData unix = 1 [(gogoproto.nullable) = true]; + WindowsData windows = 2 [(gogoproto.nullable) = true]; +} + +message UnixData { + // The owner name and group name are set when known (i.e., could be + // resolved on the source device), while the UID and GID are always set + // as they come directly from the stat() call. + string owner_name = 1; + string group_name = 2; + int32 uid = 3 [(ext.goname) = "UID"]; + int32 gid = 4 [(ext.goname) = "GID"]; +} + +message WindowsData { + // Windows file objects have a single owner, which may be a user or a + // group. We keep the name of that account, and a flag to indicate what + // type it is. + string owner_name = 1; + bool owner_is_group = 2; +} + // Request message Request {