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 ,
7273-define (SSH_TIMEOUT , 10000 ).
7374-define (REG_ATTERS , <<0 ,0 ,0 ,0 ,1 >>).
7475-define (UNIX_EPOCH , 62167219200 ).
75-
76- -define (is_set (F , Bits ),
77- ((F ) band (Bits )) == (F )).
76+ -define (MAX_PATH , 200 ).
77+ -define (is_set (F , Bits ), ((F ) band (Bits )) == (F )).
7878
7979% %--------------------------------------------------------------------
8080% % Common Test interface functions -----------------------------------
@@ -87,6 +87,7 @@ all() ->
8787 [open_close_file ,
8888 open_close_dir ,
8989 read_file ,
90+ max_path ,
9091 read_dir ,
9192 write_file ,
9293 rename_file ,
@@ -181,7 +182,8 @@ init_per_testcase(TestCase, Config) ->
181182 {sftpd_vsn , 6 }])],
182183 ssh :daemon (0 , [{subsystems , SubSystems }|Options ]);
183184 _ ->
184- SubSystems = [ssh_sftpd :subsystem_spec ([])],
185+ SubSystems = [ssh_sftpd :subsystem_spec (
186+ [{max_path , ? MAX_PATH }])],
185187 ssh :daemon (0 , [{subsystems , SubSystems }|Options ])
186188 end ,
187189
@@ -334,6 +336,23 @@ read_file(Config) when is_list(Config) ->
334336
335337 {ok , Data } = file :read_file (FileName ).
336338
339+ % %--------------------------------------------------------------------
340+ max_path (Config ) when is_list (Config ) ->
341+ PrivDir = proplists :get_value (priv_dir , Config ),
342+ FileName = filename :join (PrivDir , " test.txt" ),
343+ {Cm , Channel } = proplists :get_value (sftp , Config ),
344+ % % verify max_path limit
345+ LongFileName =
346+ filename :join (PrivDir ,
347+ " t" ++ lists :flatten (lists :duplicate (? MAX_PATH , " e" )) ++ " st.txt" ),
348+ {ok , _ } = file :copy (FileName , LongFileName ),
349+ ReqId1 = req_id (),
350+ {ok , <<? SSH_FXP_STATUS , ? UINT32 (ReqId1 ), ? UINT32 (? SSH_FX_NO_SUCH_PATH ),
351+ _ /binary >>, _ } =
352+ open_file (LongFileName , Cm , Channel , ReqId1 ,
353+ ? ACE4_READ_DATA bor ? ACE4_READ_ATTRIBUTES ,
354+ ? SSH_FXF_OPEN_EXISTING ).
355+
337356% %--------------------------------------------------------------------
338357read_dir (Config ) when is_list (Config ) ->
339358 PrivDir = proplists :get_value (priv_dir , Config ),
@@ -389,35 +408,33 @@ rename_file(Config) when is_list(Config) ->
389408 PrivDir = proplists :get_value (priv_dir , Config ),
390409 FileName = filename :join (PrivDir , " test.txt" ),
391410 NewFileName = filename :join (PrivDir , " test1.txt" ),
392- ReqId = 0 ,
411+ LongFileName =
412+ filename :join (PrivDir ,
413+ " t" ++ lists :flatten (lists :duplicate (? MAX_PATH , " e" )) ++ " st.txt" ),
393414 {Cm , Channel } = proplists :get_value (sftp , Config ),
394-
395- {ok , <<? SSH_FXP_STATUS , ? UINT32 (ReqId ),
396- ? UINT32 (? SSH_FX_OK ), _ /binary >>, _ } =
397- rename (FileName , NewFileName , Cm , Channel , ReqId , 6 , 0 ),
398-
399- NewReqId = ReqId + 1 ,
400-
401- {ok , <<? SSH_FXP_STATUS , ? UINT32 (NewReqId ),
402- ? UINT32 (? SSH_FX_OK ), _ /binary >>, _ } =
403- rename (NewFileName , FileName , Cm , Channel , NewReqId , 6 ,
404- ? SSH_FXP_RENAME_OVERWRITE ),
405-
406- NewReqId1 = NewReqId + 1 ,
407- file :copy (FileName , NewFileName ),
408-
409- % % No overwrite
410- {ok , <<? SSH_FXP_STATUS , ? UINT32 (NewReqId1 ),
411- ? UINT32 (? SSH_FX_FILE_ALREADY_EXISTS ), _ /binary >>, _ } =
412- rename (FileName , NewFileName , Cm , Channel , NewReqId1 , 6 ,
413- ? SSH_FXP_RENAME_NATIVE ),
414-
415- NewReqId2 = NewReqId1 + 1 ,
416-
417- {ok , <<? SSH_FXP_STATUS , ? UINT32 (NewReqId2 ),
418- ? UINT32 (? SSH_FX_OP_UNSUPPORTED ), _ /binary >>, _ } =
419- rename (FileName , NewFileName , Cm , Channel , NewReqId2 , 6 ,
420- ? SSH_FXP_RENAME_ATOMIC ).
415+ Version = 6 ,
416+ [begin
417+ case Action of
418+ {Code , AFile , BFile , Flags } ->
419+ ReqId = req_id (),
420+ ct :log (" ReqId = ~p ,~n Code = ~p ,~n AFile = ~p ,~n BFile = ~p ,~n Flags = ~p " ,
421+ [ReqId , Code , AFile , BFile , Flags ]),
422+ {ok , <<? SSH_FXP_STATUS , ? UINT32 (ReqId ), ? UINT32 (Code ), _ /binary >>, _ } =
423+ rename (AFile , BFile , Cm , Channel , ReqId , Version , Flags );
424+ {file_copy , AFile , BFile } ->
425+ {ok , _ } = file :copy (AFile , BFile )
426+ end
427+ end ||
428+ Action <-
429+ [{? SSH_FX_OK , FileName , NewFileName , 0 },
430+ {? SSH_FX_OK , NewFileName , FileName , ? SSH_FXP_RENAME_OVERWRITE },
431+ {file_copy , FileName , NewFileName },
432+ % % no overwrite
433+ {? SSH_FX_FILE_ALREADY_EXISTS , FileName , NewFileName , ? SSH_FXP_RENAME_NATIVE },
434+ {? SSH_FX_OP_UNSUPPORTED , FileName , NewFileName , ? SSH_FXP_RENAME_ATOMIC },
435+ % % max_path
436+ {? SSH_FX_NO_SUCH_PATH , FileName , LongFileName , 0 }]],
437+ ok .
421438
422439% %--------------------------------------------------------------------
423440mk_rm_dir (Config ) when is_list (Config ) ->
@@ -1087,3 +1104,12 @@ encode_file_type(Type) ->
10871104
10881105not_default_permissions () ->
10891106 8#600 . % % User read-write-only
1107+
1108+ req_id () ->
1109+ ReqId =
1110+ case get (req_id ) of
1111+ undefined -> 0 ;
1112+ I -> I
1113+ end ,
1114+ put (req_id , ReqId + 1 ),
1115+ ReqId .
0 commit comments