2009-08-12 5 views
0

У меня есть немного кода, который читает каталог файлов для обработки. В настоящее время я использую методы dirent.h, opendir(), readdir(). Мне сказали, что мне нужно сделать то же самое, только теперь это каталог на удаленной машине с SSH/SFTP-доступом.Существуют ли способы вызова opendir(), readdir() через SSH/SFTP?

Единственный способ, о котором я могу думать, сделать то же самое, не меняя ничего в системе, кроме моего исходного кода, - это запустить команду «ssh user @ host ls», проанализировать и обработать на основе результаты парсеров.

Реальный вопрос: есть ли способы делать opendir(), readdir() (или что-то подобное) через SSH/SFTP?

ответ

2

Самый простой способ, если вы находитесь в Linux или Mac OS X (или некоторых BSD), должен будет использовать sshfs для присоединения к файловой системе. Большинство вызовов файловой системы будут работать непосредственно без изменений.

В противном случае вы можете посмотреть sshfs's source за подсказками о том, как это происходит.

1

Да, у SFTP есть протокол для этого. Прочтите последний документ здесь: http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/

+0

Это реализовано где угодно? –

+1

Это касается меня тем, что OpenSSH, похоже, не имеет стабильного API или любой документации API, кроме комментариев в коде. –

+1

sshfs просто запускает ssh как отдельный процесс и говорит о необработанном SFTP через канал, устраняя необходимость в стабильном API – bdonlan

0

Как и в случае с OpenSSH 5.1, для этого существует ограниченная реализация. Он не полностью реализует стандарт File XFER. Поэтому я не могу проверить такие вещи, как типы файлов, но я могу сканировать сами имена файлов ... Используя код «sftp.c» в источнике OpenSSH, я просто скомпоновал adhoc main(), который можно было бы изменить по мере необходимости .. . Надеюсь, что на этот вопрос можно более подробно ответить на более поздний срок.

/* Username is a NULL terminated string 
    Host is a NULL terminated string indicating remote IP */ 
void setup_args(arglist *args, char *username, char *host) 
{ 
     // Arg init allocation 
     memset(args, '\0', sizeof(*args)); 
     args->list = NULL; 

     // Arg setup 
     addargs(args, "%s", "/usr/bin/ssh"); 
     addargs(args, "%s", "-oForwardX11 no"); 
     addargs(args, "%s", "-oForwardAgent no"); 
     addargs(args, "%s", "-oPermitLocalCommand no"); 
     addargs(args, "%s", "-oClearAllForwardings yes"); 
     addargs(args, "%s%s", "-l", username); 
     addargs(args, "%s", "-oProtocol 2"); 
     addargs(args, "%s", "-s"); 
     addargs(args, "%s", host); 
     addargs(args, "%s", "sftp"); 
} 
void run_program() 
{ 
     // Setup connection parameters. 
     int in, out; // The IO file descriptors. 
     arglist args; 
     setup_args(&args, "chenz", "172.16.22.128"); 
     connect_to_server("/usr/bin/ssh", args.list, &in, &out); 
     freeargs(&args); 

     // Create connection 
     struct sftp_conn *conn; 
     conn = do_init(in, out, copy_buffer_len, num_requests); 
     if (conn == NULL) 
       fatal("Couldn't initialise connection to server"); 

     //Get the current directory 
     char *pwd; 
     pwd = do_realpath(conn, "."); 
     printf("PWD: %s\n", pwd); 
     if (pwd == NULL) 
       fatal("Need cwd"); 

     SFTP_DIRENT** dirent; 
     do_readdir(conn, "/home/chenz", &dirent); 
     int i = 0; 
     while (dirent[i] != 0) { 
       printf("filename: %s\n", dirent[i]->filename); 
       printf("longname: %s\n", dirent[i]->longname); 
       printf("attrib:\n", dirent[i]->a); 
       i++; 
     } 

     // Clean up file descriptors 
     close(in); 
     close(out); 

     // Wait for kill signal and exit 
     while (waitpid(sshpid, NULL, 0) == -1) 
       if (errno != EINTR) 
         fatal("Couldn't wait for ssh process: %s", 
          strerror(errno)); 

     //exit(err == 0 ? 0 : 1); 
     exit(0); 
}