ssh2(SFTP)를 이용하여 linux에서 파일 디렉토리 구조 가져오기
안녕하세요 반갑습니다.
지금 현재 리눅스에서 리눅스로 ssh2 라이브러리를 이용하여 SFTP로 파일을 가져오는 것을 하고 있는데요.(qt)
기능은 간단히 말씀드리면(원격지,호스트모두 리눅스)
1. 로컬에서 지정한 n개의 원격지폴더 갯수만큼 계속 모니터링하면서 사용자가 지정한 로컬패스에 파일을 가져오고 예정된 시간이 지나면 다시 접근하여 새로 업데이트 된 파일을 가져오는 기능입니다.
전제조건
1.원격지의 폴더는 시간별일 수도 있고 종목별(사진,pdf) 일 수 있습니다. (폴더구조가 정해져있지않음)
2.폴더의 깊이는 다중트리 일 수 있습니다.(부모가 한개인데 자식이 8개 일수 도있고 100 개일 수 도 있음)
3.리눅스 특성상 확장자가 없어서 파일인지 폴더인지 구분하는 함수가 없습니다.
현재 문제가 되는점은
ssh2라이브러리에서 원격지 폴더 구조를 가져오는 함수가 없습니다. (아무리 찾아도 없습니다. 혹시 있나요? ㅠ.ㅠ)
한번 open(경로가르키기) 하고 거기에 몇개가 있는지 읽어오는데 다 하나씩 재귀함수로 다중트리를 선회하면서 open 해보고 트루(주소값 반환)면 폴더라고 간주하고 안에 들어가서 또 읽고 모든 트리를 순회할 수 있게
이렇게 재귀함수로 만들었습니다.
(만약 재귀함수가 아니면 3깊이의 트리 폴더로 들어간뒤 그폴더를 돌아와 2깊이의 파일을 읽으려면 이미 3깊이를
가리켰고 가르키고 있기때문에 다시 2 깊이를 지정해줘야하며 그렇게되면 각 깊이의 모든 파일을 읽을 수 없습니다. 왜냐면 2깊이에서 파일3개 폴더 하나라고 가정할경우 처음부터 폴더를 읽어버릴 수 있기때문입니다.)
그리고 순회하면서 파일이면 벡터에 담아놓고 로컬에서 파일리스트를 생성후 그 리스트를 다운로드 받습니다.
결론
트리구조를 가져오는 함수가 ssh2 라이브러리에 아무리 찾아도 없어 재귀함수 알고리즘을 만들었으나 속도도 느리고 추후 트리의 깊이가 깊어지고 n개의 다운로드 원격지가 많아진다면 함수스택오버플로우가 걱정됨.
다운로드 중인지 아닌지 확인하는 함수가 없어 최초 리스트를 벡터에 저장하고 10분뒤 다시 선회한후 다른벡터에 집어넣어 비교해본 뒤 modify 시간이 변동없으면 다운로드 완료된 파일이라고 가정하고 다운로드를 진행함
*단 다운로드시 작성된 파일리스트 텍스트 파일은 지워짐
저좀 도와주세요 ㅠ.ㅠ.. 읽어주셔서 감사합니다.
흠...
흠...
https://www.libssh2.org/libssh2_sftp_stat.html
https://en.wikipedia.org/wiki/Tree_traversal
작성자입니다.
답변해주신 sftp_stat이 정보를 구조체에 담아서 알려주는데
유저id,그룹id,액세스시간,수정시간,허가번호,flag, 사이즈만 알려줍니다. ㅠ.ㅠ.. 얘가 파일인지 폴더인지는 안알려줍니다.
그리고 링크걸어주신 트리 탐색 방법확인하여보니 제가 만든거랑 똑같습니다. ㅠ.ㅠ..
그리고 새로운 함수(지역변수)를 할당하여 오픈하고 읽는거를 해야하기 때문에 재귀를 피할수없을 것 같습니다ㅠㅠ
Quote:답변해주신 sftp_stat이 정보를
https://www.libssh2.org/libssh2_sftp_fstat_ex.html
https://www.gnu.org/software/libc/manual/html_node/Testing-File-Type.html
제가 링크해드린 위키피디아 항목은 call stack이 아닌 커스텀 스택/큐를 이용하여 Tree traversal을 하는 슈도 코드를 포함하고 있습니다.
커스텀 스택/큐라고 해도 크기가 무한정 커질 수 있는 건 아니지만, 어플리케이션이 직접 관리하기가 쉬워서 더 유연하게 대응할 수 있습니다. (스택이 너무 커지면 일부를 디스크에 옮긴다던가)
각 노드를 방문할 때마다 추가로 필요한 메모리는 동적으로 할당받아서 사용 및 관리하면 됩니다.
libssh2_sftp_readdir_ex 을 이용하면 안되나요?
https://www.libssh2.org/libssh2_sftp_readdir_ex.html
에 보면 마지막인자의 LIBSSH2_SFTP_ATTRIBUTES *attrsfh값으로 디렉토리인지 판단할수 없나요?
디렉토리일 경우) if(attrsfh->permissions & LIBSSH2_SFTP_S_IFDIR)
재귀호출 할 필요 없습니다.
재귀호출 할 필요 없습니다.
만약 저라면, 그냥 rsync 사용하겠습니다.
rsync 를 사용할 형편이 안된다면, sshfs 로 마운트해 놓고 간단한 shell script 를 만들던가요.
북마크용.
regcomp(), regexec()
CIRCLEQ_*, SLIST_*
tsearch(), tfind()
댓글 달기