4343 open_file_dir_v6 /1 ,
4444 read_dir /1 ,
4545 read_file /1 ,
46+ max_path /1 ,
4647 real_path /1 ,
4748 relative_path /1 ,
4849 relpath /1 ,
7172-define (SSH_TIMEOUT , 5000 ).
7273-define (REG_ATTERS , <<0 ,0 ,0 ,0 ,1 >>).
7374-define (UNIX_EPOCH , 62167219200 ).
74-
75- -define (is_set (F , Bits ),
76- ((F ) band (Bits )) == (F )).
75+ -define (MAX_PATH , 200 ).
76+ -define (is_set (F , Bits ), ((F ) band (Bits )) == (F )).
7777
7878% %--------------------------------------------------------------------
7979% % Common Test interface functions -----------------------------------
@@ -86,6 +86,7 @@ all() ->
8686 [open_close_file ,
8787 open_close_dir ,
8888 read_file ,
89+ max_path ,
8990 read_dir ,
9091 write_file ,
9192 rename_file ,
@@ -180,7 +181,8 @@ init_per_testcase(TestCase, Config) ->
180181 {sftpd_vsn , 6 }])],
181182 ssh :daemon (0 , [{subsystems , SubSystems }|Options ]);
182183 _ ->
183- SubSystems = [ssh_sftpd :subsystem_spec ([])],
184+ SubSystems = [ssh_sftpd :subsystem_spec (
185+ [{max_path , ? MAX_PATH }])],
184186 ssh :daemon (0 , [{subsystems , SubSystems }|Options ])
185187 end ,
186188
@@ -333,6 +335,23 @@ read_file(Config) when is_list(Config) ->
333335
334336 {ok , Data } = file :read_file (FileName ).
335337
338+ % %--------------------------------------------------------------------
339+ max_path (Config ) when is_list (Config ) ->
340+ PrivDir = proplists :get_value (priv_dir , Config ),
341+ FileName = filename :join (PrivDir , " test.txt" ),
342+ {Cm , Channel } = proplists :get_value (sftp , Config ),
343+ % % verify max_path limit
344+ LongFileName =
345+ filename :join (PrivDir ,
346+ " t" ++ lists :flatten (lists :duplicate (? MAX_PATH , " e" )) ++ " st.txt" ),
347+ {ok , _ } = file :copy (FileName , LongFileName ),
348+ ReqId1 = req_id (),
349+ {ok , <<? SSH_FXP_STATUS , ? UINT32 (ReqId1 ), ? UINT32 (? SSH_FX_NO_SUCH_PATH ),
350+ _ /binary >>, _ } =
351+ open_file (LongFileName , Cm , Channel , ReqId1 ,
352+ ? ACE4_READ_DATA bor ? ACE4_READ_ATTRIBUTES ,
353+ ? SSH_FXF_OPEN_EXISTING ).
354+
336355% %--------------------------------------------------------------------
337356read_dir (Config ) when is_list (Config ) ->
338357 PrivDir = proplists :get_value (priv_dir , Config ),
@@ -388,35 +407,33 @@ rename_file(Config) when is_list(Config) ->
388407 PrivDir = proplists :get_value (priv_dir , Config ),
389408 FileName = filename :join (PrivDir , " test.txt" ),
390409 NewFileName = filename :join (PrivDir , " test1.txt" ),
391- ReqId = 0 ,
410+ LongFileName =
411+ filename :join (PrivDir ,
412+ " t" ++ lists :flatten (lists :duplicate (? MAX_PATH , " e" )) ++ " st.txt" ),
392413 {Cm , Channel } = proplists :get_value (sftp , Config ),
393-
394- {ok , <<? SSH_FXP_STATUS , ? UINT32 (ReqId ),
395- ? UINT32 (? SSH_FX_OK ), _ /binary >>, _ } =
396- rename (FileName , NewFileName , Cm , Channel , ReqId , 6 , 0 ),
397-
398- NewReqId = ReqId + 1 ,
399-
400- {ok , <<? SSH_FXP_STATUS , ? UINT32 (NewReqId ),
401- ? UINT32 (? SSH_FX_OK ), _ /binary >>, _ } =
402- rename (NewFileName , FileName , Cm , Channel , NewReqId , 6 ,
403- ? SSH_FXP_RENAME_OVERWRITE ),
404-
405- NewReqId1 = NewReqId + 1 ,
406- file :copy (FileName , NewFileName ),
407-
408- % % No overwrite
409- {ok , <<? SSH_FXP_STATUS , ? UINT32 (NewReqId1 ),
410- ? UINT32 (? SSH_FX_FILE_ALREADY_EXISTS ), _ /binary >>, _ } =
411- rename (FileName , NewFileName , Cm , Channel , NewReqId1 , 6 ,
412- ? SSH_FXP_RENAME_NATIVE ),
413-
414- NewReqId2 = NewReqId1 + 1 ,
415-
416- {ok , <<? SSH_FXP_STATUS , ? UINT32 (NewReqId2 ),
417- ? UINT32 (? SSH_FX_OP_UNSUPPORTED ), _ /binary >>, _ } =
418- rename (FileName , NewFileName , Cm , Channel , NewReqId2 , 6 ,
419- ? SSH_FXP_RENAME_ATOMIC ).
414+ Version = 6 ,
415+ [begin
416+ case Action of
417+ {Code , AFile , BFile , Flags } ->
418+ ReqId = req_id (),
419+ ct :log (" ReqId = ~p ,~n Code = ~p ,~n AFile = ~p ,~n BFile = ~p ,~n Flags = ~p " ,
420+ [ReqId , Code , AFile , BFile , Flags ]),
421+ {ok , <<? SSH_FXP_STATUS , ? UINT32 (ReqId ), ? UINT32 (Code ), _ /binary >>, _ } =
422+ rename (AFile , BFile , Cm , Channel , ReqId , Version , Flags );
423+ {file_copy , AFile , BFile } ->
424+ {ok , _ } = file :copy (AFile , BFile )
425+ end
426+ end ||
427+ Action <-
428+ [{? SSH_FX_OK , FileName , NewFileName , 0 },
429+ {? SSH_FX_OK , NewFileName , FileName , ? SSH_FXP_RENAME_OVERWRITE },
430+ {file_copy , FileName , NewFileName },
431+ % % no overwrite
432+ {? SSH_FX_FILE_ALREADY_EXISTS , FileName , NewFileName , ? SSH_FXP_RENAME_NATIVE },
433+ {? SSH_FX_OP_UNSUPPORTED , FileName , NewFileName , ? SSH_FXP_RENAME_ATOMIC },
434+ % % max_path
435+ {? SSH_FX_NO_SUCH_PATH , FileName , LongFileName , 0 }]],
436+ ok .
420437
421438% %--------------------------------------------------------------------
422439mk_rm_dir (Config ) when is_list (Config ) ->
@@ -1078,3 +1095,12 @@ encode_file_type(Type) ->
10781095
10791096not_default_permissions () ->
10801097 8#600 . % % User read-write-only
1098+
1099+ req_id () ->
1100+ ReqId =
1101+ case get (req_id ) of
1102+ undefined -> 0 ;
1103+ I -> I
1104+ end ,
1105+ put (req_id , ReqId + 1 ),
1106+ ReqId .
0 commit comments