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 + -
显示快捷键?