ssh_xfer.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,026 行 · 第 1/3 页
ERL
1,026 行
?SSH_FILEXFER_TYPE_SOCKET -> socket; ?SSH_FILEXFER_TYPE_CHAR_DEVICE -> char_device; ?SSH_FILEXFER_TYPE_BLOCK_DEVICE -> block_device; ?SSH_FILEXFER_TYPE_FIFO -> fifo end.encode_attrib_bits(Bits) -> encode_bits( fun(readonly) -> ?SSH_FILEXFER_ATTR_FLAGS_READONLY; (system) -> ?SSH_FILEXFER_ATTR_FLAGS_SYSTEM; (hidden) -> ?SSH_FILEXFER_ATTR_FLAGS_HIDDEN; (case_insensitive) -> ?SSH_FILEXFER_ATTR_FLAGS_CASE_INSENSITIVE; (arcive) -> ?SSH_FILEXFER_ATTR_FLAGS_ARCHIVE; (encrypted) -> ?SSH_FILEXFER_ATTR_FLAGS_ENCRYPTED; (compressed) -> ?SSH_FILEXFER_ATTR_FLAGS_COMPRESSED; (sparse) -> ?SSH_FILEXFER_ATTR_FLAGS_SPARSE; (append_only) -> ?SSH_FILEXFER_ATTR_FLAGS_APPEND_ONLY; (immutable) -> ?SSH_FILEXFER_ATTR_FLAGS_IMMUTABLE; (sync) -> ?SSH_FILEXFER_ATTR_FLAGS_SYNC end, Bits).decode_attrib_bits(F) -> decode_bits(F, [{?SSH_FILEXFER_ATTR_FLAGS_READONLY, readonly}, {?SSH_FILEXFER_ATTR_FLAGS_SYSTEM, system}, {?SSH_FILEXFER_ATTR_FLAGS_HIDDEN, hidden}, {?SSH_FILEXFER_ATTR_FLAGS_CASE_INSENSITIVE, case_insensitive}, {?SSH_FILEXFER_ATTR_FLAGS_ARCHIVE, arcive}, {?SSH_FILEXFER_ATTR_FLAGS_ENCRYPTED, encrypted}, {?SSH_FILEXFER_ATTR_FLAGS_COMPRESSED, compressed}, {?SSH_FILEXFER_ATTR_FLAGS_SPARSE, sparse}, {?SSH_FILEXFER_ATTR_FLAGS_APPEND_ONLY, append_only}, {?SSH_FILEXFER_ATTR_FLAGS_IMMUTABLE, immutable}, {?SSH_FILEXFER_ATTR_FLAGS_SYNC, sync}]).%% %% Encode file attributes%% encode_ATTR(Vsn, A) -> {Flags,As} = encode_As(Vsn, [{size, A#ssh_xfer_attr.size}, {ownergroup, A#ssh_xfer_attr.owner}, {ownergroup, A#ssh_xfer_attr.group}, {permissions, A#ssh_xfer_attr.permissions}, {acmodtime, A#ssh_xfer_attr.atime}, {acmodtime, A#ssh_xfer_attr.mtime}, {accesstime, A#ssh_xfer_attr.atime}, {subsecond_times, A#ssh_xfer_attr.atime_nseconds}, {createtime, A#ssh_xfer_attr.createtime}, {subsecond_times, A#ssh_xfer_attr.createtime_nseconds}, {modifytime, A#ssh_xfer_attr.mtime}, {subsecond_times, A#ssh_xfer_attr.mtime_nseconds}, {acl, A#ssh_xfer_attr.acl}, {bits, A#ssh_xfer_attr.attrib_bits}, {extended, A#ssh_xfer_attr.extensions}], 0, []), Type = encode_file_type(A#ssh_xfer_attr.type), ?dbg(true, "encode_ATTR: Vsn=~p A=~p As=~p Flags=~p Type=~p", [Vsn, A, As, Flags, Type]), Result = list_to_binary([?uint32(Flags), if Vsn >= 5 -> ?byte(Type); true -> (<<>>) end, As]), %% ?dbg(true, " Result=~p\n", [Result]), Result.encode_As(Vsn, [{_AName, undefined}|As], Flags, Acc) -> encode_As(Vsn, As, Flags, Acc);encode_As(Vsn, [{AName, X}|As], Flags, Acc) -> case AName of size -> encode_As(Vsn, As,Flags bor ?SSH_FILEXFER_ATTR_SIZE, [?uint64(X) | Acc]); ownergroup when Vsn=<4 -> encode_As(Vsn, As,Flags bor ?SSH_FILEXFER_ATTR_UIDGID, [?uint32(X) | Acc]); ownergroup when Vsn>=5 -> X1 = list_to_binary(integer_to_list(X)), % KOLLA 腉ARE OCH GRUPPNAMN H腞 encode_As(Vsn, As,Flags bor ?SSH_FILEXFER_ATTR_OWNERGROUP, [?binary(X1) | Acc]); permissions -> encode_As(Vsn, As,Flags bor ?SSH_FILEXFER_ATTR_PERMISSIONS, [?uint32(X) | Acc]); acmodtime when Vsn=<3 -> encode_As(Vsn, As,Flags bor ?SSH_FILEXFER_ATTR_ACMODTIME, [?uint32(X) | Acc]); accesstime when Vsn>=5 -> encode_As(Vsn, As, Flags bor ?SSH_FILEXFER_ATTR_ACCESSTIME, [?uint64(X) | Acc]); createtime when Vsn>=5-> encode_As(Vsn, As, Flags bor ?SSH_FILEXFER_ATTR_CREATETIME, [?uint64(X) | Acc]); modifytime when Vsn>=5 -> encode_As(Vsn, As, Flags bor ?SSH_FILEXFER_ATTR_MODIFYTIME, [?uint64(X) | Acc]); subsecond_times when Vsn>=5 -> encode_As(Vsn, As, Flags bor ?SSH_FILEXFER_ATTR_SUBSECOND_TIMES, [?uint64(X) | Acc]); acl when Vsn >=5 -> encode_As(Vsn, As, Flags bor ?SSH_FILEXFER_ATTR_ACL, [encode_acl(X) | Acc]); bits when Vsn>=5 -> F = encode_attrib_bits(X), encode_As(Vsn, As, Flags bor ?SSH_FILEXFER_ATTR_BITS, [?uint32(F) | Acc]); extended -> encode_As(Vsn, As, Flags bor ?SSH_FILEXFER_ATTR_EXTENDED, [encode_extensions(X) | Acc]); _ -> encode_As(Vsn, As, Flags, Acc) end;encode_As(_Vsn, [], Flags, Acc) -> {Flags, reverse(Acc)}.decode_ATTR(Vsn, <<?UINT32(Flags), Tail/binary>>) -> ?dbg(true, "decode_ATTR: Vsn=~p Flags=~p Tail=~p\n", [Vsn, Flags, Tail]), {Type,Tail2} = if Vsn =< 3 -> {?SSH_FILEXFER_TYPE_UNKNOWN, Tail}; Vsn >= 5 -> <<?BYTE(T), TL/binary>> = Tail, {T, TL} end, decode_As(Vsn, [{size, #ssh_xfer_attr.size}, {ownergroup, #ssh_xfer_attr.owner}, {ownergroup, #ssh_xfer_attr.group}, {permissions, #ssh_xfer_attr.permissions}, {acmodtime, #ssh_xfer_attr.atime}, {acmodtime, #ssh_xfer_attr.mtime}, {accesstime, #ssh_xfer_attr.atime}, {subsecond_times, #ssh_xfer_attr.atime_nseconds}, {createtime, #ssh_xfer_attr.createtime}, {subsecond_times, #ssh_xfer_attr.createtime_nseconds}, {modifytime, #ssh_xfer_attr.mtime}, {subsecond_times, #ssh_xfer_attr.mtime_nseconds}, {acl, #ssh_xfer_attr.acl}, {bits, #ssh_xfer_attr.attrib_bits}, {extended, #ssh_xfer_attr.extensions}], #ssh_xfer_attr { type = decode_file_type(Type) }, Flags, Tail2).decode_As(Vsn, [{AName, AField}|As], R, Flags, Tail) -> ?dbg(false, "decode_As: Vsn=~p AName=~p AField=~p Flags=~p Tail=~p\n", [Vsn, AName, AField, Flags, Tail]), case AName of size when ?is_set(?SSH_FILEXFER_ATTR_SIZE, Flags) -> <<?UINT64(X), Tail2/binary>> = Tail, decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); ownergroup when ?is_set(?SSH_FILEXFER_ATTR_UIDGID, Flags),Vsn=<3 -> <<?UINT32(X), Tail2/binary>> = Tail, decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); ownergroup when ?is_set(?SSH_FILEXFER_ATTR_OWNERGROUP, Flags),Vsn>=5 -> <<?UINT32(Len), Bin:Len/binary, Tail2/binary>> = Tail, X = binary_to_list(Bin), ?dbg(true, "ownergroup X=~p\n", [X]), decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); permissions when ?is_set(?SSH_FILEXFER_ATTR_PERMISSIONS,Flags),Vsn>=5-> <<?UINT32(X), Tail2/binary>> = Tail, decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); permissions when ?is_set(?SSH_FILEXFER_ATTR_PERMISSIONS,Flags),Vsn=<3-> <<?UINT32(X), Tail2/binary>> = Tail, R1 = setelement(AField, R, X), Type = case X band ?S_IFMT of ?S_IFDIR -> directory; ?S_IFCHR -> char_device; ?S_IFBLK -> block_device; ?S_IFIFO -> fifi; ?S_IFREG -> regular; ?S_IFSOCK -> socket; ?S_IFLNK -> symlink; _ -> unknown end, decode_As(Vsn, As, R1#ssh_xfer_attr { type=Type}, Flags, Tail2); acmodtime when ?is_set(?SSH_FILEXFER_ATTR_ACMODTIME,Flags),Vsn=<3 -> <<?UINT32(X), Tail2/binary>> = Tail, decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); accesstime when ?is_set(?SSH_FILEXFER_ATTR_ACCESSTIME,Flags),Vsn>=5 -> <<?UINT64(X), Tail2/binary>> = Tail, decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); modifytime when ?is_set(?SSH_FILEXFER_ATTR_MODIFYTIME,Flags),Vsn>=5 -> <<?UINT64(X), Tail2/binary>> = Tail, decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); createtime when ?is_set(?SSH_FILEXFER_ATTR_CREATETIME,Flags),Vsn>=5 -> <<?UINT64(X), Tail2/binary>> = Tail, decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); subsecond_times when ?is_set(?SSH_FILEXFER_ATTR_SUBSECOND_TIMES,Flags),Vsn>=5 -> <<?UINT32(X), Tail2/binary>> = Tail, decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); acl when ?is_set(?SSH_FILEXFER_ATTR_ACL, Flags), Vsn>=5 -> {X,Tail2} = decode_acl(Tail), decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); bits when ?is_set(?SSH_FILEXFER_ATTR_BITS, Flags), Vsn >=5 -> <<?UINT32(Y), Tail2/binary>> = Tail, X = decode_attrib_bits(Y), decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); extended when ?is_set(?SSH_FILEXFER_ATTR_EXTENDED, Flags) -> {X,Tail2} = decode_extended(Tail), decode_As(Vsn, As, setelement(AField, R, X), Flags, Tail2); _ -> decode_As(Vsn, As, R, Flags, Tail) end;decode_As(_Vsn, [], R, _, Tail) -> {R, Tail}. decode_names(_Vsn, 0, _Data) -> [];decode_names(Vsn, I, <<?UINT32(Len), FileName:Len/binary, ?UINT32(LLen), _LongName:LLen/binary, Tail/binary>>) when Vsn =< 3 -> Name = binary_to_list(FileName), ?dbg(true, "decode_names: ~p\n", [Name]), {A, Tail2} = decode_ATTR(Vsn, Tail), [{Name, A} | decode_names(Vsn, I-1, Tail2)];decode_names(Vsn, I, <<?UINT32(Len), FileName:Len/binary, Tail/binary>>) when Vsn >= 4 -> Name = binary_to_list(FileName), ?dbg(true, "decode_names: ~p\n", [Name]), {A, Tail2} = decode_ATTR(Vsn, Tail), [{Name, A} | decode_names(Vsn, I-1, Tail2)].encode_names(Vsn, NamesAndAttrs) -> lists:mapfoldl(fun(N, L) -> encode_name(Vsn, N, L) end, 0, NamesAndAttrs).encode_name(Vsn, {Name,Attr}, Len) when Vsn =< 3 -> NLen = length(Name), %%?dbg(true, "encode_name: Vsn=~p Name=~p Attr=~p\n", %% [Vsn, Name, Attr]), EncAttr = encode_ATTR(Vsn, Attr), ALen = size(EncAttr), NewLen = Len + NLen*2 + 4 + 4 + ALen, {[<<?UINT32(NLen)>>, Name, <<?UINT32(NLen)>>, Name, EncAttr], NewLen};encode_name(Vsn, {Name,Attr}, Len) when Vsn >= 4 -> NLen = length(Name), EncAttr = encode_ATTR(Vsn, Attr), ALen = size(EncAttr), {[<<?UINT32(NLen)>>, Name, EncAttr], Len + 4 + NLen + ALen}.encode_acl(ACLList) -> Count = length(ACLList), [?uint32(Count) | encode_acl_items(ACLList)].encode_acl_items([ACE|As]) -> Type = encode_ace_type(ACE#ssh_xfer_ace.type), Flag = encode_ace_flag(ACE#ssh_xfer_ace.flag), Mask = encode_ace_mask(ACE#ssh_xfer_ace.mask), Who = list_to_binary(ACE#ssh_xfer_ace.who), [?uint32(Type), ?uint32(Flag), ?uint32(Mask), ?binary(Who) | encode_acl_items(As)];encode_acl_items([]) -> [].decode_acl(<<?UINT32(Count), Tail/binary>>) -> decode_acl_items(Count, Tail, []).decode_acl_items(0, Tail, Acc) -> {reverse(Acc), Tail};decode_acl_items(I, <<?UINT32(Type), ?UINT32(Flag), ?UINT32(Mask), ?UINT32(WLen), BWho:WLen/binary, Tail/binary>>, Acc) -> decode_acl_items(I-1, Tail, [#ssh_xfer_ace { type = decode_ace_type(Type), flag = decode_ace_flag(Flag), mask = decode_ace_mask(Mask), who = binary_to_list(BWho)} | Acc]).encode_extensions(Exts) -> Count = length(Exts), [?uint32(Count) | encode_ext(Exts)].encode_ext([{Type, Data} | Exts]) -> [?string(Type), ?string(Data) | encode_ext(Exts)];encode_ext([]) -> [].decode_extended(<<?UINT32(Count), Tail/binary>>) -> decode_ext(Count, Tail, []).decode_ext(0, Tail, Acc) -> {reverse(Acc), Tail};decode_ext(I, <<?UINT32(TLen), Type:TLen/binary, ?UINT32(DLen), Data:DLen/binary, Tail/binary>>, Acc) -> decode_ext(I-1, Tail, [{binary_to_list(Type), Data}|Acc]).%% Encode bit encoded flagsencode_bits(Fun, BitNames) -> encode_bits(Fun, 0, BitNames).encode_bits(Fun, F, [Bit|BitNames]) -> encode_bits(Fun, Fun(Bit) bor F, BitNames);encode_bits(_Fun, F, []) -> F.%% Decode bit encoded flagsdecode_bits(F, [{Bit,BitName}|Bits]) -> if F band Bit == Bit -> [BitName | decode_bits(F, Bits)]; true -> decode_bits(F, Bits) end;decode_bits(_F, []) -> [].%% %% iolist size%% bsize(B) ->%% bsize(B, 0).%% bsize(B, S) when binary(B) ->%% case B of%% <<>> -> S;%% _ -> S + size(B)%% end;%% bsize([], S) ->%% S;%% bsize(I, S) when integer(I) ->%% S + 1;%% bsize([A|B], S) ->%% bsize(B, S + bsize(A)).connect_timeout(Opts) -> proplists:get_value(connect_timeout, Opts, ?DEFAULT_TIMEOUT).
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?